b4bc23078a
Notable changes: - Remove the comments in port impl, that's easily getting to in-consistence - Sync the jerryscript-port.h and 05.PORT-API.md - Fixes the invalid comment in port codes JerryScript-DCO-1.0-Signed-off-by: Yonggang Luo luoyonggang@gmail.com
121 lines
3.8 KiB
C
121 lines
3.8 KiB
C
/* Copyright JS Foundation and other contributors, http://js.foundation
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#include "jerryscript-port.h"
|
|
|
|
#if defined(_WIN32)
|
|
|
|
#include <windows.h>
|
|
|
|
#include <time.h>
|
|
#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 */
|
|
|
|
/*
|
|
* If you take the limit of SYSTEMTIME (last millisecond in 30827) then you end up with
|
|
* a FILETIME of 0x7fff35f4f06c58f0 by using SystemTimeToFileTime(). However, if you put
|
|
* 0x7fffffffffffffff into FileTimeToSystemTime() then you will end up in the year 30828,
|
|
* although this date is invalid for SYSTEMTIME. Any larger value (0x8000000000000000 and above)
|
|
* causes FileTimeToSystemTime() to fail.
|
|
* https://docs.microsoft.com/en-us/windows/win32/api/minwinbase/ns-minwinbase-systemtime
|
|
* https://docs.microsoft.com/en-us/windows/win32/api/minwinbase/ns-minwinbase-filetime
|
|
*/
|
|
#define UNIX_EPOCH_DATE_1601_01_02 -11644387200000LL /* unit: ms */
|
|
#define UNIX_EPOCH_DATE_30827_12_29 9106702560000000LL /* unit: ms */
|
|
|
|
/**
|
|
* Convert unix time to a FILETIME value.
|
|
*
|
|
* 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)
|
|
{
|
|
LONGLONG ll = (LONGLONG) t * TICKS_PER_MS + UNIX_EPOCH_IN_TICKS;
|
|
|
|
/* FILETIME values before the epoch are invalid. */
|
|
if (ll < 0)
|
|
{
|
|
ll = 0;
|
|
}
|
|
|
|
ft_p->dwLowDateTime = (DWORD) ll;
|
|
ft_p->dwHighDateTime = (DWORD) (ll >> 32);
|
|
} /* unix_time_to_filetime */
|
|
|
|
/**
|
|
* Convert a FILETIME to a unix time value.
|
|
*
|
|
* @return unix time
|
|
*/
|
|
static double
|
|
filetime_to_unix_time (LPFILETIME ft_p)
|
|
{
|
|
ULARGE_INTEGER date;
|
|
date.HighPart = ft_p->dwHighDateTime;
|
|
date.LowPart = ft_p->dwLowDateTime;
|
|
return (double) (((LONGLONG) date.QuadPart - UNIX_EPOCH_IN_TICKS) / TICKS_PER_MS);
|
|
} /* filetime_to_unix_time */
|
|
|
|
int32_t
|
|
jerry_port_local_tza (double unix_ms)
|
|
{
|
|
FILETIME utc;
|
|
FILETIME local;
|
|
SYSTEMTIME utc_sys;
|
|
SYSTEMTIME local_sys;
|
|
|
|
/*
|
|
* If the time is earlier than the date 1601-01-02, then always using date 1601-01-02 to
|
|
* query time zone adjustment. This date (1601-01-02) will make sure both UTC and local
|
|
* time succeed with Win32 API. The date 1601-01-01 may lead to a win32 api failure, as
|
|
* 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)
|
|
{
|
|
unix_ms = (double) 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)
|
|
{
|
|
unix_ms = (double) UNIX_EPOCH_DATE_30827_12_29;
|
|
}
|
|
unix_time_to_filetime (unix_ms, &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);
|
|
}
|
|
|
|
return 0;
|
|
} /* jerry_port_local_tza */
|
|
|
|
double
|
|
jerry_port_current_time (void)
|
|
{
|
|
FILETIME ft;
|
|
GetSystemTimeAsFileTime (&ft);
|
|
return filetime_to_unix_time (&ft);
|
|
} /* jerry_port_current_time */
|
|
|
|
#endif /* defined(_WIN32) */
|