Skip to content

Commit 4539f42

Browse files
committed
Testing new Date(-8640000000000000) and fixes date for win32
JerryScript-DCO-1.0-Signed-off-by: Yonggang Luo [email protected]
1 parent d2e0d71 commit 4539f42

File tree

3 files changed

+30
-21
lines changed

3 files changed

+30
-21
lines changed

jerry-core/ecma/builtin-objects/ecma-builtin-helpers-date.c

+5-1
Original file line numberDiff line numberDiff line change
@@ -467,12 +467,16 @@ ecma_number_t
467467
ecma_date_make_date (ecma_number_t day, /**< day value */
468468
ecma_number_t time) /**< time value */
469469
{
470+
ecma_number_t date;
470471
if (!ecma_number_is_finite (day) || !ecma_number_is_finite (time))
471472
{
472473
return ecma_number_make_nan ();
473474
}
474475

475-
return day + time;
476+
date = day + time;
477+
if (date <= -8640000000000001LL || date >= 8640000000000001LL)
478+
return ecma_number_make_nan ();
479+
return date;
476480
} /* ecma_date_make_date */
477481

478482
/**

jerry-port/win/jerry-port-win-date.c

+17-20
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@
2323
#include <winbase.h>
2424
#include <winnt.h>
2525

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

2929
/*
3030
* If you take the limit of SYSTEMTIME (last millisecond in 30827) then you end up with
@@ -44,15 +44,9 @@
4444
* https://support.microsoft.com/en-us/help/167296/how-to-convert-a-unix-time-t-to-a-win32-filetime-or-systemtime
4545
*/
4646
static void
47-
unix_time_to_filetime (double t, LPFILETIME ft_p)
47+
unix_time_to_filetime (LONGLONG t, LPFILETIME ft_p)
4848
{
49-
LONGLONG ll = (LONGLONG) t * TICKS_PER_MS + UNIX_EPOCH_IN_TICKS;
50-
51-
/* FILETIME values before the epoch are invalid. */
52-
if (ll < 0)
53-
{
54-
ll = 0;
55-
}
49+
LONGLONG ll = t * TICKS_PER_MS + UNIX_EPOCH_IN_TICKS;
5650

5751
ft_p->dwLowDateTime = (DWORD) ll;
5852
ft_p->dwHighDateTime = (DWORD) (ll >> 32);
@@ -63,13 +57,15 @@ unix_time_to_filetime (double t, LPFILETIME ft_p)
6357
*
6458
* @return unix time
6559
*/
66-
static double
60+
static LONGLONG
6761
filetime_to_unix_time (LPFILETIME ft_p)
6862
{
6963
ULARGE_INTEGER date;
64+
LONGLONG ll;
7065
date.HighPart = ft_p->dwHighDateTime;
7166
date.LowPart = ft_p->dwLowDateTime;
72-
return (double) (((LONGLONG) date.QuadPart - UNIX_EPOCH_IN_TICKS) / TICKS_PER_MS);
67+
ll = date.QuadPart - UNIX_EPOCH_IN_TICKS;
68+
return ll / TICKS_PER_MS;
7369
} /* filetime_to_unix_time */
7470

7571
/**
@@ -85,6 +81,7 @@ jerry_port_local_tza (double unix_ms)
8581
FILETIME local;
8682
SYSTEMTIME utc_sys;
8783
SYSTEMTIME local_sys;
84+
LONGLONG t = (LONGLONG) (unix_ms);
8885

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

10198
/* Like above, do not use the last supported day */
102-
if (unix_ms > (double) UNIX_EPOCH_DATE_30827_12_29)
99+
if (t > UNIX_EPOCH_DATE_30827_12_29)
103100
{
104-
unix_ms = (double) UNIX_EPOCH_DATE_30827_12_29;
101+
t = UNIX_EPOCH_DATE_30827_12_29;
105102
}
106-
unix_time_to_filetime (unix_ms, &utc);
103+
unix_time_to_filetime (t, &utc);
107104

108105
if (FileTimeToSystemTime (&utc, &utc_sys) && SystemTimeToTzSpecificLocalTime (NULL, &utc_sys, &local_sys)
109106
&& SystemTimeToFileTime (&local_sys, &local))
110107
{
111-
double unix_local = filetime_to_unix_time (&local);
112-
return (int32_t) (unix_local - unix_ms);
108+
LONGLONG unix_local = filetime_to_unix_time (&local);
109+
return (int32_t) (unix_local - t);
113110
}
114111

115112
return 0;
@@ -125,7 +122,7 @@ jerry_port_current_time (void)
125122
{
126123
FILETIME ft;
127124
GetSystemTimeAsFileTime (&ft);
128-
return filetime_to_unix_time (&ft);
125+
return (double) filetime_to_unix_time (&ft);
129126
} /* jerry_port_current_time */
130127

131128
#endif /* defined(_WIN32) */

tests/jerry/date-getters.js

+8
Original file line numberDiff line numberDiff line change
@@ -110,8 +110,16 @@ assert (new Date(-1, -1, -1, -1, -1, -1, -1, -1).getMilliseconds() === 999);
110110
assert (isNaN(new Date(20000000, 0).getFullYear()));
111111
assert (new Date(0, 0).getFullYear() === 1900);
112112
assert (new Date(1.2, 0).getFullYear() === 1901);
113+
114+
/* 7. test case */
115+
/* 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).
116+
A time value supports a slightly smaller range of -8,640,000,000,000,000 to 8,640,000,000,000,000 milliseconds. */
113117
assert((new Date(8640000000000000).getFullYear()) == 275760);
114118
assert(isNaN(new Date(8640000000000001).getFullYear()));
119+
assert((new Date(-8640000000000000).getFullYear()) == -271821);
120+
assert(isNaN(new Date(-8640000000000001).getFullYear()));
121+
122+
/* 8. test case */
115123
assert((new Date(-271821, 3, 21).getFullYear()) == -271821);
116124
assert(isNaN(new Date(1970, 0, -100000000).getFullYear()));
117125
assert(new Date(1970, 0, -100000000 + 1).getFullYear() == -271821);

0 commit comments

Comments
 (0)