mirror of
https://github.com/4jcraft/4jcraft.git
synced 2026-05-08 13:27:17 +00:00
feat: add stubs for Windows system time functions
This commit is contained in:
parent
42035b71d8
commit
8d24ebdad8
|
|
@ -18,6 +18,7 @@
|
|||
#include <fnmatch.h>
|
||||
#include <time.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#define TRUE true
|
||||
#define FALSE false
|
||||
|
|
@ -160,6 +161,18 @@ typedef struct _LINUXSTUBS_FIND_HANDLE {
|
|||
char pattern[MAX_PATH];
|
||||
} _LINUXSTUBS_FIND_HANDLE;
|
||||
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/minwinbase/ns-minwinbase-systemtime
|
||||
typedef struct _SYSTEMTIME {
|
||||
WORD wYear;
|
||||
WORD wMonth;
|
||||
WORD wDayOfWeek;
|
||||
WORD wDay;
|
||||
WORD wHour;
|
||||
WORD wMinute;
|
||||
WORD wSecond;
|
||||
WORD wMilliseconds;
|
||||
} SYSTEMTIME, *PSYSTEMTIME, *LPSYSTEMTIME;
|
||||
|
||||
#define TLS_OUT_OF_INDEXES ((DWORD)0xFFFFFFFF)
|
||||
|
||||
typedef pthread_mutex_t RTL_CRITICAL_SECTION;
|
||||
|
|
@ -520,4 +533,120 @@ static inline BOOL FindClose(HANDLE hFindFile)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
// internal helper: convert FILETIME (100ns since 1601) to time_t (seconds since 1970)
|
||||
static inline time_t _FileTimeToTimeT(const FILETIME& ft)
|
||||
{
|
||||
ULONGLONG val = ((ULONGLONG)ft.dwHighDateTime << 32) | ft.dwLowDateTime;
|
||||
const ULONGLONG EPOCH_DIFF = 116444736000000000ULL; // 100ns intervals between 1601-01-01 and 1970-01-01
|
||||
return (time_t)((val - EPOCH_DIFF) / 10000000ULL);
|
||||
}
|
||||
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getsystemtime
|
||||
static inline VOID GetSystemTime(LPSYSTEMTIME lpSystemTime)
|
||||
{
|
||||
struct timespec ts;
|
||||
#ifdef CLOCK_REALTIME
|
||||
clock_gettime(CLOCK_REALTIME, &ts);
|
||||
#else
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
ts.tv_sec = tv.tv_sec;
|
||||
ts.tv_nsec = tv.tv_usec * 1000;
|
||||
#endif
|
||||
struct tm tm;
|
||||
gmtime_r(&ts.tv_sec, &tm); // UTC
|
||||
|
||||
lpSystemTime->wYear = tm.tm_year + 1900;
|
||||
lpSystemTime->wMonth = tm.tm_mon + 1;
|
||||
lpSystemTime->wDayOfWeek = tm.tm_wday; // 0 = Sunday
|
||||
lpSystemTime->wDay = tm.tm_mday;
|
||||
lpSystemTime->wHour = tm.tm_hour;
|
||||
lpSystemTime->wMinute = tm.tm_min;
|
||||
lpSystemTime->wSecond = tm.tm_sec;
|
||||
lpSystemTime->wMilliseconds = ts.tv_nsec / 1000000; // ns to ms
|
||||
}
|
||||
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getlocaltime
|
||||
static inline VOID GetLocalTime(LPSYSTEMTIME lpSystemTime)
|
||||
{
|
||||
struct timespec ts;
|
||||
#ifdef CLOCK_REALTIME
|
||||
clock_gettime(CLOCK_REALTIME, &ts);
|
||||
#else
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
ts.tv_sec = tv.tv_sec;
|
||||
ts.tv_nsec = tv.tv_usec * 1000;
|
||||
#endif
|
||||
struct tm tm;
|
||||
localtime_r(&ts.tv_sec, &tm); // local time
|
||||
|
||||
lpSystemTime->wYear = tm.tm_year + 1900;
|
||||
lpSystemTime->wMonth = tm.tm_mon + 1;
|
||||
lpSystemTime->wDayOfWeek = tm.tm_wday;
|
||||
lpSystemTime->wDay = tm.tm_mday;
|
||||
lpSystemTime->wHour = tm.tm_hour;
|
||||
lpSystemTime->wMinute = tm.tm_min;
|
||||
lpSystemTime->wSecond = tm.tm_sec;
|
||||
lpSystemTime->wMilliseconds = ts.tv_nsec / 1000000;
|
||||
}
|
||||
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/timezoneapi/nf-timezoneapi-systemtimetofiletime
|
||||
static inline BOOL SystemTimeToFileTime(const SYSTEMTIME *lpSystemTime, LPFILETIME lpFileTime)
|
||||
{
|
||||
struct tm tm = {0};
|
||||
tm.tm_year = lpSystemTime->wYear - 1900;
|
||||
tm.tm_mon = lpSystemTime->wMonth - 1;
|
||||
tm.tm_mday = lpSystemTime->wDay;
|
||||
tm.tm_hour = lpSystemTime->wHour;
|
||||
tm.tm_min = lpSystemTime->wMinute;
|
||||
tm.tm_sec = lpSystemTime->wSecond;
|
||||
tm.tm_isdst = -1; // unknown
|
||||
|
||||
// Convert to time_t assuming UTC
|
||||
time_t t;
|
||||
// Portable UTC mktime: temporarily set TZ to UTC
|
||||
char *tz_old = getenv("TZ");
|
||||
setenv("TZ", "UTC", 1);
|
||||
tzset();
|
||||
t = mktime(&tm);
|
||||
if (tz_old)
|
||||
setenv("TZ", tz_old, 1);
|
||||
else
|
||||
unsetenv("TZ");
|
||||
tzset();
|
||||
|
||||
if (t == (time_t)-1)
|
||||
return FALSE;
|
||||
|
||||
// Add milliseconds
|
||||
ULONGLONG ft = ((ULONGLONG)t + 11644473600ULL) * 10000000ULL;
|
||||
ft += lpSystemTime->wMilliseconds * 10000ULL; // 1ms = 10000 * 100ns
|
||||
|
||||
lpFileTime->dwLowDateTime = (DWORD)(ft & 0xFFFFFFFF);
|
||||
lpFileTime->dwHighDateTime = (DWORD)(ft >> 32);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// https://learn.microsoft.com/en-us/windows/win32/api/timezoneapi/nf-timezoneapi-filetimetosystemtime
|
||||
static inline BOOL FileTimeToSystemTime(const FILETIME *lpFileTime, LPSYSTEMTIME lpSystemTime)
|
||||
{
|
||||
time_t t = _FileTimeToTimeT(*lpFileTime);
|
||||
ULONGLONG ft = ((ULONGLONG)lpFileTime->dwHighDateTime << 32) | lpFileTime->dwLowDateTime;
|
||||
ULONGLONG remainder100ns = ft % 10000000ULL; // 1 second = 10^7 * 100ns
|
||||
|
||||
struct tm tm;
|
||||
gmtime_r(&t, &tm); // UTC
|
||||
|
||||
lpSystemTime->wYear = tm.tm_year + 1900;
|
||||
lpSystemTime->wMonth = tm.tm_mon + 1;
|
||||
lpSystemTime->wDayOfWeek = tm.tm_wday;
|
||||
lpSystemTime->wDay = tm.tm_mday;
|
||||
lpSystemTime->wHour = tm.tm_hour;
|
||||
lpSystemTime->wMinute = tm.tm_min;
|
||||
lpSystemTime->wSecond = tm.tm_sec;
|
||||
lpSystemTime->wMilliseconds = (WORD)(remainder100ns / 10000); // 1ms = 10000 * 100ns
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#endif // LINUXSTUBS_H
|
||||
Loading…
Reference in a new issue