2 * Windows Date providers
4 * Platform specific links:
6 * - http://msdn.microsoft.com/en-us/library/windows/desktop/ms725473(v=vs.85).aspx
9 #include "duk_internal.h"
11 /* The necessary #includes are in place in duk_config.h. */
13 #if defined(DUK_USE_DATE_NOW_WINDOWS) || defined(DUK_USE_DATE_TZO_WINDOWS)
14 /* Shared Windows helpers. */
15 DUK_LOCAL
void duk__convert_systime_to_ularge(const SYSTEMTIME
*st
, ULARGE_INTEGER
*res
) {
17 if (SystemTimeToFileTime(st
, &ft
) == 0) {
18 DUK_D(DUK_DPRINT("SystemTimeToFileTime() failed, returning 0"));
21 res
->LowPart
= ft
.dwLowDateTime
;
22 res
->HighPart
= ft
.dwHighDateTime
;
25 DUK_LOCAL
void duk__set_systime_jan1970(SYSTEMTIME
*st
) {
26 DUK_MEMZERO((void *) st
, sizeof(*st
));
29 st
->wDayOfWeek
= 4; /* not sure whether or not needed; Thursday */
31 DUK_ASSERT(st
->wHour
== 0);
32 DUK_ASSERT(st
->wMinute
== 0);
33 DUK_ASSERT(st
->wSecond
== 0);
34 DUK_ASSERT(st
->wMilliseconds
== 0);
36 #endif /* defined(DUK_USE_DATE_NOW_WINDOWS) || defined(DUK_USE_DATE_TZO_WINDOWS) */
38 #ifdef DUK_USE_DATE_NOW_WINDOWS
39 DUK_INTERNAL duk_double_t
duk_bi_date_get_now_windows(duk_context
*ctx
) {
40 /* Suggested step-by-step method from documentation of RtlTimeToSecondsSince1970:
41 * http://msdn.microsoft.com/en-us/library/windows/desktop/ms724928(v=vs.85).aspx
44 ULARGE_INTEGER tmp1
, tmp2
;
49 duk__convert_systime_to_ularge((const SYSTEMTIME
*) &st1
, &tmp1
);
51 duk__set_systime_jan1970(&st2
);
52 duk__convert_systime_to_ularge((const SYSTEMTIME
*) &st2
, &tmp2
);
54 /* Difference is in 100ns units, convert to milliseconds w/o fractions */
55 return (duk_double_t
) ((tmp1
.QuadPart
- tmp2
.QuadPart
) / 10000LL);
57 #endif /* DUK_USE_DATE_NOW_WINDOWS */
60 #if defined(DUK_USE_DATE_TZO_WINDOWS)
61 DUK_INTERNAL_DECL duk_int_t
duk_bi_date_get_local_tzoffset_windows(duk_double_t d
) {
70 /* XXX: handling of timestamps outside Windows supported range.
71 * How does Windows deal with dates before 1600? Does windows
72 * support all Ecmascript years (like -200000 and +200000)?
73 * Should equivalent year mapping be used here too? If so, use
74 * a shared helper (currently integrated into timeval-to-parts).
77 /* Use the approach described in "Remarks" of FileTimeToLocalFileTime:
78 * http://msdn.microsoft.com/en-us/library/windows/desktop/ms724277(v=vs.85).aspx
81 duk__set_systime_jan1970(&st1
);
82 duk__convert_systime_to_ularge((const SYSTEMTIME
*) &st1
, &tmp1
);
83 tmp2
.QuadPart
= (ULONGLONG
) (d
* 10000.0); /* millisec -> 100ns units since jan 1, 1970 */
84 tmp2
.QuadPart
+= tmp1
.QuadPart
; /* input 'd' in Windows UTC, 100ns units */
86 ft1
.dwLowDateTime
= tmp2
.LowPart
;
87 ft1
.dwHighDateTime
= tmp2
.HighPart
;
88 FileTimeToSystemTime((const FILETIME
*) &ft1
, &st2
);
89 if (SystemTimeToTzSpecificLocalTime((LPTIME_ZONE_INFORMATION
) NULL
, &st2
, &st3
) == 0) {
90 DUK_D(DUK_DPRINT("SystemTimeToTzSpecificLocalTime() failed, return tzoffset 0"));
93 duk__convert_systime_to_ularge((const SYSTEMTIME
*) &st3
, &tmp3
);
95 /* Positive if local time ahead of UTC. */
96 return (duk_int_t
) (((LONGLONG
) tmp3
.QuadPart
- (LONGLONG
) tmp2
.QuadPart
) / 10000000LL); /* seconds */
98 #endif /* DUK_USE_DATE_TZO_WINDOWS */