2626#define UNIX_EPOCH_IN_TICKS 116444736000000000ull /* difference between 1970 and 1601 */
2727#define TICKS_PER_MS 10000ull /* 1 tick is 100 nanoseconds */
2828
29+ /*
30+ * If you take the limit of SYSTEMTIME (last millisecond in 30827) then you end up with
31+ * a FILETIME of 0x7fff35f4f06c58f0 by using SystemTimeToFileTime(). However, if you put
32+ * 0x7fffffffffffffff into FileTimeToSystemTime() then you will end up in the year 30828,
33+ * although this date is invalid for SYSTEMTIME. Any larger value (0x8000000000000000 and above)
34+ * causes FileTimeToSystemTime() to fail.
35+ * https://docs.microsoft.com/en-us/windows/win32/api/minwinbase/ns-minwinbase-systemtime
36+ * https://docs.microsoft.com/en-us/windows/win32/api/minwinbase/ns-minwinbase-filetime
37+ */
38+ #define UNIX_EPOCH_DATE_1601_01_02 -11644387200000LL /* unit: ms */
39+ #define UNIX_EPOCH_DATE_30827_12_29 9106702560000000LL /* unit: ms */
40+
2941/**
3042 * Convert unix time to a FILETIME value.
3143 *
@@ -44,7 +56,7 @@ unix_time_to_filetime (double t, LPFILETIME ft_p)
4456
4557 ft_p -> dwLowDateTime = (DWORD ) ll ;
4658 ft_p -> dwHighDateTime = (DWORD ) (ll >> 32 );
47- } /* unix_time_to_file_time */
59+ } /* unix_time_to_filetime */
4860
4961/**
5062 * Convert a FILETIME to a unix time value.
@@ -58,7 +70,7 @@ filetime_to_unix_time (LPFILETIME ft_p)
5870 date .HighPart = ft_p -> dwHighDateTime ;
5971 date .LowPart = ft_p -> dwLowDateTime ;
6072 return (double ) (((LONGLONG ) date .QuadPart - UNIX_EPOCH_IN_TICKS ) / TICKS_PER_MS );
61- } /* FileTimeToUnixTimeMs */
73+ } /* filetime_to_unix_time */
6274
6375/**
6476 * Default implementation of jerry_port_local_tza.
@@ -74,6 +86,23 @@ jerry_port_local_tza (double unix_ms)
7486 SYSTEMTIME utc_sys ;
7587 SYSTEMTIME local_sys ;
7688
89+ /*
90+ * If the time is earlier than the date 1601-01-02, then always using date 1601-01-02 to
91+ * query time zone adjustment. This date (1601-01-02) will make sure both UTC and local
92+ * time succeed with Win32 API. The date 1601-01-01 may lead to a win32 api failure, as
93+ * after converting between local time and utc time, the time may be earlier than 1601-01-01
94+ * in UTC time, that exceeds the FILETIME representation range.
95+ */
96+ if (unix_ms < (double ) UNIX_EPOCH_DATE_1601_01_02 )
97+ {
98+ unix_ms = (double ) UNIX_EPOCH_DATE_1601_01_02 ;
99+ }
100+
101+ /* Like above, do not use the last supported day */
102+ if (unix_ms > (double ) UNIX_EPOCH_DATE_30827_12_29 )
103+ {
104+ unix_ms = (double ) UNIX_EPOCH_DATE_30827_12_29 ;
105+ }
77106 unix_time_to_filetime (unix_ms , & utc );
78107
79108 if (FileTimeToSystemTime (& utc , & utc_sys ) && SystemTimeToTzSpecificLocalTime (NULL , & utc_sys , & local_sys )
0 commit comments