das2C
das core C utilities (v3)
Loading...
Searching...
No Matches
win_gtod.h
1/* Replacement for gettimeofday for Windows
2 *
3 * The usual FILETIME to Unix time conversion: count 100 ns ticks since
4 * 1601-01-01, subtract the ticks up to 1970-01-01, divide down to seconds.
5 * Written here around 2015, likely with a web search open, but not copied
6 * from anywhere in particular, so no license notice is carried.
7 *
8 * Known limits, left alone for now:
9 *
10 * - Millisecond resolution only. tv_usec comes from SYSTEMTIME's
11 * wMilliseconds, though FILETIME counts 100 ns ticks. To fix, take
12 * tv_usec from (time - EPOCH) % 10000000 / 10, and read the clock with
13 * GetSystemTimeAsFileTime(), or GetSystemTimePreciseAsFileTime() on
14 * Windows 8 and up, which also skips the SYSTEMTIME round trip.
15 *
16 * - struct timeval's members are long, 32 bits on Windows, so tv_sec runs
17 * out in January 2038. That's winsock's struct, not this function.
18 */
19
20#include <stdint.h>
21
22static int win_gettimeofday(struct timeval * tp, struct timezone * tzp)
23{
24 // Note: some broken versions only have 8 trailing zero's, the correct epoch has 9 trailing zero's
25 // This magic number is the number of 100 nanosecond intervals since January 1, 1601 (UTC)
26 // until 00:00:00 January 1, 1970
27 static const uint64_t EPOCH = ((uint64_t) 116444736000000000ULL);
28
29 SYSTEMTIME system_time;
30 FILETIME file_time;
31 uint64_t time;
32
33 GetSystemTime( &system_time );
34 SystemTimeToFileTime( &system_time, &file_time );
35 time = ((uint64_t)file_time.dwLowDateTime ) ;
36 time += ((uint64_t)file_time.dwHighDateTime) << 32;
37
38 tp->tv_sec = (long) ((time - EPOCH) / 10000000L);
39 tp->tv_usec = (long) (system_time.wMilliseconds * 1000);
40 return 0;
41}