Skip to content

Commit

Permalink
Testing new Date(-8640000000000000) and fixes date for win32
Browse files Browse the repository at this point in the history
JerryScript-DCO-1.0-Signed-off-by: Yonggang Luo [email protected]
  • Loading branch information
lygstate committed Nov 14, 2024
1 parent 7115b29 commit 12ca421
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 21 deletions.
6 changes: 5 additions & 1 deletion jerry-core/ecma/builtin-objects/ecma-builtin-helpers-date.c
Original file line number Diff line number Diff line change
Expand Up @@ -467,12 +467,16 @@ ecma_number_t
ecma_date_make_date (ecma_number_t day, /**< day value */
ecma_number_t time) /**< time value */
{
ecma_number_t date;
if (!ecma_number_is_finite (day) || !ecma_number_is_finite (time))
{
return ecma_number_make_nan ();
}

return day + time;
date = day + time;
if (date < -8640000000000000LL || date > 8640000000000000LL)
return ecma_number_make_nan ();
return date;
} /* ecma_date_make_date */

/**
Expand Down
37 changes: 17 additions & 20 deletions jerry-port/win/jerry-port-win-date.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@
#include <winbase.h>
#include <winnt.h>

#define UNIX_EPOCH_IN_TICKS 116444736000000000ull /* difference between 1970 and 1601 */
#define TICKS_PER_MS 10000ull /* 1 tick is 100 nanoseconds */
#define UNIX_EPOCH_IN_TICKS 116444736000000000LL /* difference between 1970 and 1601 */
#define TICKS_PER_MS 10000LL /* 1 tick is 100 nanoseconds */

/*
* If you take the limit of SYSTEMTIME (last millisecond in 30827) then you end up with
Expand All @@ -44,15 +44,9 @@
* https://support.microsoft.com/en-us/help/167296/how-to-convert-a-unix-time-t-to-a-win32-filetime-or-systemtime
*/
static void
unix_time_to_filetime (double t, LPFILETIME ft_p)
unix_time_to_filetime (LONGLONG t, LPFILETIME ft_p)
{
LONGLONG ll = (LONGLONG) t * TICKS_PER_MS + UNIX_EPOCH_IN_TICKS;

/* FILETIME values before the epoch are invalid. */
if (ll < 0)
{
ll = 0;
}
LONGLONG ll = t * TICKS_PER_MS + UNIX_EPOCH_IN_TICKS;

ft_p->dwLowDateTime = (DWORD) ll;
ft_p->dwHighDateTime = (DWORD) (ll >> 32);
Expand All @@ -63,13 +57,15 @@ unix_time_to_filetime (double t, LPFILETIME ft_p)
*
* @return unix time
*/
static double
static LONGLONG
filetime_to_unix_time (LPFILETIME ft_p)
{
ULARGE_INTEGER date;
LONGLONG ll;
date.HighPart = ft_p->dwHighDateTime;
date.LowPart = ft_p->dwLowDateTime;
return (double) (((LONGLONG) date.QuadPart - UNIX_EPOCH_IN_TICKS) / TICKS_PER_MS);
ll = date.QuadPart - UNIX_EPOCH_IN_TICKS;
return ll / TICKS_PER_MS;
} /* filetime_to_unix_time */

/**
Expand All @@ -85,6 +81,7 @@ jerry_port_local_tza (double unix_ms)
FILETIME local;
SYSTEMTIME utc_sys;
SYSTEMTIME local_sys;
LONGLONG t = (LONGLONG) (unix_ms);

/*
* If the time is earlier than the date 1601-01-02, then always using date 1601-01-02 to
Expand All @@ -93,23 +90,23 @@ jerry_port_local_tza (double unix_ms)
* after converting between local time and utc time, the time may be earlier than 1601-01-01
* in UTC time, that exceeds the FILETIME representation range.
*/
if (unix_ms < (double) UNIX_EPOCH_DATE_1601_01_02)
if (t < UNIX_EPOCH_DATE_1601_01_02)
{
unix_ms = (double) UNIX_EPOCH_DATE_1601_01_02;
t = UNIX_EPOCH_DATE_1601_01_02;
}

/* Like above, do not use the last supported day */
if (unix_ms > (double) UNIX_EPOCH_DATE_30827_12_29)
if (t > UNIX_EPOCH_DATE_30827_12_29)
{
unix_ms = (double) UNIX_EPOCH_DATE_30827_12_29;
t = UNIX_EPOCH_DATE_30827_12_29;
}
unix_time_to_filetime (unix_ms, &utc);
unix_time_to_filetime (t, &utc);

if (FileTimeToSystemTime (&utc, &utc_sys) && SystemTimeToTzSpecificLocalTime (NULL, &utc_sys, &local_sys)
&& SystemTimeToFileTime (&local_sys, &local))
{
double unix_local = filetime_to_unix_time (&local);
return (int32_t) (unix_local - unix_ms);
LONGLONG unix_local = filetime_to_unix_time (&local);
return (int32_t) (unix_local - t);
}

return 0;
Expand All @@ -125,7 +122,7 @@ jerry_port_current_time (void)
{
FILETIME ft;
GetSystemTimeAsFileTime (&ft);
return filetime_to_unix_time (&ft);
return (double) filetime_to_unix_time (&ft);
} /* jerry_port_current_time */

#endif /* defined(_WIN32) */
8 changes: 8 additions & 0 deletions tests/jerry/date-getters.js
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,16 @@ assert (new Date(-1, -1, -1, -1, -1, -1, -1, -1).getMilliseconds() === 999);
assert (isNaN(new Date(20000000, 0).getFullYear()));
assert (new Date(0, 0).getFullYear() === 1900);
assert (new Date(1.2, 0).getFullYear() === 1901);

/* 7. test case */
/* A Number can exactly represent all integers from -9,007,199,254,740,992 to 9,007,199,254,740,992 (21.1.2.8 and 21.1.2.6).
A time value supports a slightly smaller range of -8,640,000,000,000,000 to 8,640,000,000,000,000 milliseconds. */
assert((new Date(8640000000000000).getFullYear()) == 275760);
assert(isNaN(new Date(8640000000000001).getFullYear()));
assert((new Date(-8640000000000000).getFullYear()) == -271821);
assert(isNaN(new Date(-8640000000000001).getFullYear()));

/* 8. test case */
assert((new Date(-271821, 3, 21).getFullYear()) == -271821);
assert(isNaN(new Date(1970, 0, -100000000).getFullYear()));
assert(new Date(1970, 0, -100000000 + 1).getFullYear() == -271821);
Expand Down

0 comments on commit 12ca421

Please sign in to comment.