問題描述
我想在 Windows 上獲得一個精確的本地時區時間戳,并將以下內容存盤在一個結構中:
- 天
- 月
- 年
- 小時
- 分鐘
- 第二
- 納秒
我正在尋找這個問題的 C 解決方案。
我的理解是 Windows 只能提供微秒級的粒度,但無論如何我想將該資訊存盤為納秒級。
我的用例
以下是我的用例的一些詳細資訊,以防它們相關。如果您不關心我的用例,可以跳過本節。
我正在撰寫一個處理事件的程式。我無法在事件發生時訂閱它們,而是需要定期輪詢事件源。事件源不僅包含新事件,還包含事件的完整歷史。
我需要創建一個時間戳,所以我只能從源處理比這個時間戳更新的事件。
同一毫秒內可能發生多個事件,因此毫秒粒度對于我的用例來說太粗略了。
我還將我的時間戳保存到持久存盤中,以便程式停止或程式崩潰時不會丟失最后處理事件的時間。
我試過的
下面是我第一次嘗試這樣做。這可能是完全錯誤的,在這種情況下,請跳轉到我正在尋求幫助的內容。
void get_timestamp_now_local_timezone(timestamp *tstamp) {
SYSTEMTIME st;
SYSTEMTIME stLocal;
FILETIME ft;
GetSystemTimePreciseAsFileTime(&ft);
FileTimeToSystemTime(&ft, &st);
SystemTimeToTzSpecificLocalTime(NULL, &st, &stLocal);
ULARGE_INTEGER large_int;
large_int.LowPart = ft.dwLowDateTime;
large_int.HighPart = ft.dwHighDateTime;
ULONGLONG timeStamp = large_int.QuadPart;
/* FILETIME has 100-nanosecond interval granularity */
ULONGLONG nanoseconds = (timeStamp % 10000000) * 100;
tstamp->year = stLocal.wYear;
tstamp->month = stLocal.wMonth;
tstamp->day = stLocal.wDay;
tstamp->hour = stLocal.wHour;
tstamp->minute = stLocal.wMinute;
tstamp->second = stLocal.wSecond;
tstamp->nanoseconds = nanoseconds;
}
我擔心此代碼可能出現幾個錯誤:
可能的錯誤 1
GetSystemTimePreciseAsFileTime()以 UTC 格式回傳時間。我擔心以 UTC 格式操作FILETIME以獲取本地時區的納秒可能是不正確的,因為閏毫秒1秒,因此時區之間可能會有所不同。
可能的錯誤 2
我不確定我ULARGE_INTEGER是否正確復制到。FILETIME我試圖遵循檔案頁面上所說的內容:
您應該將檔案時間的低位和高位部分復制到 ULARGE_INTEGER 結構,對QuadPart成員執行 64 位運算,并將LowPart和HighPart成員復制到FILETIME結構中
沒有對應的例子,所以我可能做錯了。
我正在尋求幫助
我上面的嘗試可能是完全錯誤的,我可能會叫錯樹。我更多地包含它以表明我在來到 Stack Overflow 之前嘗試自己解決這個問題。
我想幫助我解決我在上面的問題描述中描述的問題,或者通過 A) 解釋如何解決問題;或 B)如果我對解決方案的嘗試很接近(我對此表示懷疑),請指出我應該做些什么來解決我對解決方案的嘗試。
1我被告知不存在閏毫秒(我不知道為什么我認為它們存在)
uj5u.com熱心網友回復:
看起來我的問題的答案是使用當地時間是錯誤的方式,正如@chux 指出的那樣 - 恢復莫妮卡和@RbMm在評論中。
起初我認為我的時間戳需要在本地時間,因為我的事件具有本地時間時間戳,但在進一步閱讀 Microsoft 檔案后,我發現我的事件具有 UTC 時間戳。(如果有人感興趣,可以在這個問題中找到有關我嘗試處理的事件的更多詳細資訊。)
GetSystemTimePreciseAsFileTime()回傳 UTC 時間戳,因此我不需要執行任何轉換。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/460356.html
上一篇:C 中ReadConsoleOutputAttribute函式的使用
下一篇:權限提升和訪問令牌權限修改
