/**
 * Helper function to get the time value of the start of a year.
 *
 * See also:
 *          ECMA-262 v5, 15.9.1.3
 *
 * @return  time value of the start of a year
 */
static inline ecma_number_t __attr_always_inline___
ecma_date_time_from_year (ecma_number_t year) /**< year value */
{
  JERRY_ASSERT (!ecma_number_is_nan (year));

  return ECMA_DATE_MS_PER_DAY * ecma_date_day_from_year (year);
} /* ecma_date_time_from_year */
/**
 * Helper function to get month from time value.
 *
 * See also:
 *          ECMA-262 v5, 15.9.1.4
 *
 * @return month number
 */
ecma_number_t
ecma_date_month_from_time (ecma_number_t time) /**< time value */
{
  JERRY_ASSERT (!ecma_number_is_nan (time));

  ecma_number_t year = ecma_date_year_from_time (time);
  int day_within_year = (int) (ecma_date_day (time) - ecma_date_day_from_year (year));

  JERRY_ASSERT (day_within_year >= 0);

  if (day_within_year <= 30)
  {
    return 0;
  }

  day_within_year -= ecma_date_in_leap_year (year);

  JERRY_ASSERT (day_within_year < 365);

  for (int i = 0; i < 10; i++)
  {
    if (day_within_year <= ecma_date_month_end_day[i])
    {
      return i + 1;
    }
  }

  return 11;
} /* ecma_date_month_from_time */
/**
 * Unit test's main function.
 */
int
main ()
{
  /* int ecma_date_day (time)*/

  TEST_ASSERT (ecma_date_day (0) == 0);
  TEST_ASSERT (ecma_date_day (MS_PER_DAY) == 1);

  /* ecma_number_t ecma_date_time_within_day (time) */

  TEST_ASSERT (ecma_date_time_within_day (0) == 0);
  TEST_ASSERT (ecma_date_time_within_day (42) == 42);
  TEST_ASSERT (ecma_date_time_within_day (42.51) == 42.51);
  TEST_ASSERT (ecma_date_time_within_day (MS_PER_DAY + 42) == 42);

  /* int ecma_date_days_in_year (year) */

  TEST_ASSERT (ecma_date_days_in_year (0) == 366);
  TEST_ASSERT (ecma_date_days_in_year (1600) == 366);
  TEST_ASSERT (ecma_date_days_in_year (1603) == 365);
  TEST_ASSERT (ecma_date_days_in_year (1900) == 365);
  TEST_ASSERT (ecma_date_days_in_year (1970) == 365);
  TEST_ASSERT (ecma_date_days_in_year (2000) == 366);
  TEST_ASSERT (ecma_date_days_in_year (2000.45) == 366);
  TEST_ASSERT (ecma_date_days_in_year (2012) == 366);
  TEST_ASSERT (ecma_date_days_in_year (2015) == 365);
  TEST_ASSERT (ecma_date_days_in_year (285616 + 1970) == 365);
  TEST_ASSERT (ecma_date_days_in_year (-1970) == 365);

  /* int ecma_date_day_from_year (year) */

  TEST_ASSERT (ecma_date_day_from_year (1969) == -365);
  TEST_ASSERT (ecma_date_day_from_year (1970) == 0);
  TEST_ASSERT (ecma_date_day_from_year (1971) == 365);
  TEST_ASSERT (ecma_date_day_from_year (2000) == 10957);

  /* int ecma_date_year_from_time (time) */

  TEST_ASSERT (ecma_date_year_from_time (0) == 1970);
  TEST_ASSERT (ecma_date_year_from_time (0) == 1970);
  TEST_ASSERT (ecma_date_year_from_time (MS_PER_DAY) == 1970);
  TEST_ASSERT (ecma_date_year_from_time ((MS_PER_DAY) * (ecma_number_t) 365 - 1) == 1970);
  TEST_ASSERT (ecma_date_year_from_time (MS_PER_DAY * (ecma_number_t) 365) == 1971);
  TEST_ASSERT (ecma_date_year_from_time (MS_PER_DAY * (ecma_number_t) (365 * (2015 - 1970)))
                == 2014);
  TEST_ASSERT (ecma_date_year_from_time (MS_PER_DAY * (ecma_number_t) (365.25 * (2015 - 1970)))
                == 2015);
  TEST_ASSERT (ecma_date_year_from_time (-MS_PER_YEAR) == 1969);
  TEST_ASSERT (ecma_date_year_from_time (-1970 * MS_PER_YEAR) == 1);
  TEST_ASSERT (ecma_date_year_from_time (START_OF_GREGORIAN_CALENDAR) == 0);
  TEST_ASSERT (ecma_date_year_from_time (START_OF_GREGORIAN_CALENDAR - 1) == -1);
  TEST_ASSERT (ecma_date_year_from_time (START_OF_GREGORIAN_CALENDAR - 3 * MS_PER_YEAR) == -3);

  /* int ecma_date_day_within_year (time) */

  /* FIXME: Implement */

  /* int ecma_date_month_from_time  (time) */

  TEST_ASSERT (ecma_date_month_from_time (START_OF_GREGORIAN_CALENDAR) == 0);
  TEST_ASSERT (ecma_date_month_from_time (0) == 0);
  TEST_ASSERT (ecma_date_month_from_time (-MS_PER_DAY) == 11);
  TEST_ASSERT (ecma_date_month_from_time (31 * MS_PER_DAY) == 1);

  /* int ecma_date_date_from_time  (time) */

  TEST_ASSERT (ecma_date_date_from_time (START_OF_GREGORIAN_CALENDAR) == 1);
  TEST_ASSERT (ecma_date_date_from_time (0) == 1);
  TEST_ASSERT (ecma_date_date_from_time (-MS_PER_DAY) == 31);
  TEST_ASSERT (ecma_date_date_from_time (31 * MS_PER_DAY) == 1);

  /* int ecma_date_week_day (ecma_number_t time) */

  /* FIXME: Implement */

  /* ecma_number_t ecma_date_local_tza () */

  /* FIXME: Implement */

  /* ecma_number_t ecma_date_daylight_saving_ta (time) */

  /* FIXME: Implement */

  /* ecma_number_t ecma_date_local_time (time) */

  /* FIXME: Implement */

  /* ecma_number_t ecma_date_utc (time) */

  /* FIXME: Implement */

  /* ecma_number_t ecma_date_hour_from_time (time) */

  TEST_ASSERT (ecma_date_hour_from_time (START_OF_GREGORIAN_CALENDAR) == 0);
  TEST_ASSERT (ecma_date_hour_from_time (0) == 0);
  TEST_ASSERT (ecma_date_hour_from_time (-MS_PER_DAY) == 0);
  TEST_ASSERT (ecma_date_hour_from_time (-1) == 23);

  /* ecma_number_t ecma_date_min_from_time (time) */

  TEST_ASSERT (ecma_date_min_from_time (START_OF_GREGORIAN_CALENDAR) == 0);
  TEST_ASSERT (ecma_date_min_from_time (0) == 0);
  TEST_ASSERT (ecma_date_min_from_time (-MS_PER_DAY) == 0);
  TEST_ASSERT (ecma_date_min_from_time (-1) == 59);

  /* ecma_number_t ecma_date_sec_from_time (time) */

  TEST_ASSERT (ecma_date_sec_from_time (START_OF_GREGORIAN_CALENDAR) == 0);
  TEST_ASSERT (ecma_date_sec_from_time (0) == 0);
  TEST_ASSERT (ecma_date_sec_from_time (-MS_PER_DAY) == 0);
  TEST_ASSERT (ecma_date_sec_from_time (-1) == 59);

  /* ecma_number_t ecma_date_ms_from_time (time) */

  TEST_ASSERT (ecma_date_ms_from_time (START_OF_GREGORIAN_CALENDAR) == 0);
  TEST_ASSERT (ecma_date_ms_from_time (0) == 0);
  TEST_ASSERT (ecma_date_ms_from_time (-MS_PER_DAY) == 0);
  TEST_ASSERT (ecma_date_ms_from_time (-1) == 999);

  /* ecma_number_t ecma_date_make_time (hour, min, sec, ms) */

  /* FIXME: Implement */

  /* ecma_number_t ecma_date_make_day (year, month, date) */

  TEST_ASSERT (ecma_date_make_day (1970, 0, 1) == 0);
  TEST_ASSERT (ecma_date_make_day (1970, -1, 1) == -31);
  TEST_ASSERT (ecma_date_make_day (1970, 0, 2.5) == 1);
  TEST_ASSERT (ecma_date_make_day (1970, 1, 35) == 65);
  TEST_ASSERT (ecma_date_make_day (1970, 13, 35) == 430);
  TEST_ASSERT (ecma_date_make_day (2016, 2, 1) == 16861);

  /* ecma_number_t ecma_date_make_date (day, time) */

  /* FIXME: Implement */

  /* ecma_number_t ecma_date_time_clip (year) */

  /* FIXME: Implement */

  return 0;
} /* main */
/**
 * Unit test's main function.
 */
int
main (int __attr_unused___ argc,
      char __attr_unused___ **argv)
{
  /* int ecma_date_day (time)*/

  JERRY_ASSERT (ecma_date_day (0) == 0);
  JERRY_ASSERT (ecma_date_day (MS_PER_DAY) == 1);

  /* ecma_number_t ecma_date_time_within_day (time) */

  JERRY_ASSERT (ecma_date_time_within_day (0) == 0);
  JERRY_ASSERT (ecma_date_time_within_day (42) == 42);
  JERRY_ASSERT (ecma_date_time_within_day (42.51) == 42.51);
  JERRY_ASSERT (ecma_date_time_within_day (MS_PER_DAY + 42) == 42);

  /* int ecma_date_days_in_year (year) */

  JERRY_ASSERT (ecma_date_days_in_year (0) == 366);
  JERRY_ASSERT (ecma_date_days_in_year (1600) == 366);
  JERRY_ASSERT (ecma_date_days_in_year (1603) == 365);
  JERRY_ASSERT (ecma_date_days_in_year (1900) == 365);
  JERRY_ASSERT (ecma_date_days_in_year (1970) == 365);
  JERRY_ASSERT (ecma_date_days_in_year (2000) == 366);
  JERRY_ASSERT (ecma_date_days_in_year (2000.45) == 366);
  JERRY_ASSERT (ecma_date_days_in_year (2012) == 366);
  JERRY_ASSERT (ecma_date_days_in_year (2015) == 365);
  JERRY_ASSERT (ecma_date_days_in_year (285616 + 1970) == 365);
  JERRY_ASSERT (ecma_date_days_in_year (-1970) == 365);

  /* int ecma_date_day_from_year (year) */

  JERRY_ASSERT (ecma_date_day_from_year (1969) == -365);
  JERRY_ASSERT (ecma_date_day_from_year (1970) == 0);
  JERRY_ASSERT (ecma_date_day_from_year (1971) == 365);
  JERRY_ASSERT (ecma_date_day_from_year (2000) == 10957);

  /* int ecma_date_year_from_time (time) */

  JERRY_ASSERT (ecma_date_year_from_time (0) == 1970);
  JERRY_ASSERT (ecma_date_year_from_time (MS_PER_DAY) == 1970);
  JERRY_ASSERT (ecma_date_year_from_time ((MS_PER_DAY) * (ecma_number_t) 365 - 1) == 1970);
  JERRY_ASSERT (ecma_date_year_from_time (MS_PER_DAY * (ecma_number_t) 365) == 1971);
  JERRY_ASSERT (ecma_date_year_from_time (MS_PER_DAY * (ecma_number_t) (365 * (2015 - 1970)))
                == 2014);
  JERRY_ASSERT (ecma_date_year_from_time (MS_PER_DAY * (ecma_number_t) (365.25 * (2015 - 1970)))
                == 2015);

  /* int ecma_date_day_within_year (time) */

  /* FIXME: Implement */

  /* int ecma_date_month_from_time  (time) */

  /* FIXME: Implement */

  /* int ecma_date_date_from_time  (time) */

  /* FIXME: Implement */

  /* int ecma_date_week_day (ecma_number_t time) */

  /* FIXME: Implement */

  /* ecma_number_t ecma_date_local_tza () */

  /* FIXME: Implement */

  /* ecma_number_t ecma_date_daylight_saving_ta (time) */

  /* FIXME: Implement */

  /* ecma_number_t ecma_date_local_time (time) */

  /* FIXME: Implement */

  /* ecma_number_t ecma_date_utc (time) */

  /* FIXME: Implement */

  /* ecma_number_t ecma_date_hour_from_time (time) */

  /* FIXME: Implement */

  /* ecma_number_t ecma_date_min_from_time (time) */

  /* FIXME: Implement */

  /* ecma_number_t ecma_date_sec_from_time (time) */

  /* FIXME: Implement */

  /* ecma_number_t ecma_date_ms_from_time (time) */

  /* FIXME: Implement */

  /* ecma_number_t ecma_date_make_time (hour, min, sec, ms) */

  /* FIXME: Implement */

  /* ecma_number_t ecma_date_make_day (year, month, date) */

  JERRY_ASSERT (ecma_date_make_day (1970, 0, 1) == 0);
  JERRY_ASSERT (ecma_date_make_day (1970, 0, 2.5) == 1);
  JERRY_ASSERT (ecma_date_make_day (1970, 1, 35) == 65);
  JERRY_ASSERT (ecma_date_make_day (1970, 13, 35) == 430);
  JERRY_ASSERT (ecma_date_make_day (2016, 2, 1) == 16861);

  /* ecma_number_t ecma_date_make_date (day, time) */

  /* FIXME: Implement */

  /* ecma_number_t ecma_date_time_clip (year) */

  /* FIXME: Implement */

  return 0;
} /* main */