簡體   English   中英

將 Win32 時代的納秒添加到 Go 時間

[英]Add nanoseconds from Win32 epoch to Go time

我正在嘗試使用 Go 處理一些 WMI 計數器(作為學習 Go 的一部分),並試圖弄清楚如何生成必要的時間對象。

基礎是 Win32 紀元 (1601-01-01),樣本時間戳是 13224382394716547600ns(或者更確切地說,132243823947165476 100ns 單位)。

這是我嘗試過的:

測試 1(添加納秒)

win_epoch := time.Date(1601,1,1, 0, 0, 0, 0, time.UTC)
current_ts_1 := win_epoch.Add(13224382394716547600*time.Nanosecond)

測試 2(添加天數)

win_epoch := time.Date(1601,1,1, 0, 0, 0, 0, time.UTC)
current_ts_2 := win_epoch.AddDate(0,0,(132243823947165476/10000000 / 3600 / 24))

測試 1 中的current_ts_1因溢出錯誤而失敗。

測試 2 中的current_ts_2只給我日期級別的分辨率。

理想情況下,我能夠獲得毫秒級的分辨率。 是否存在不溢出傳遞給.Add()的 Duration 並仍然獲得此分辨率的方法?

這種轉換需要處理一些巨大的數字。 您的示例時間 13,224,382,394,716,547,600 太大而無法裝入 int64(最大 9,223,372,036,854,775,807),但確實適合 unit64。

處理此問題時不能使用 time.Duration,因為這是一個 int64 納秒計數; 正如文檔所說“表示將最大可表示持續時間限制為大約 290 年”。 這就是您第一次嘗試失敗的原因。

然而,還有另一種創建時間的方法在func Unix(sec int64, nsec int64) Time效果更好。 這需要 unix 格式的數據,這是自 1970 年 1 月 1 日 UTC 以來的時間(或 11644473600000000000 自windows epoch以來表示為 ns )。

使用此信息可以執行轉換:

func main() {
    const unixTimeBaseAsWin = 11644473600000000000 // The unix base time (January 1, 1970 UTC) as ns since Win32 epoch (1601-01-01) 
    const nsToSecFactor = 1000000000

    timeToConvert := uint64(13224382394716547600)

    unixsec := int64(timeToConvert  - unixTimeBaseAsWin ) / nsToSecFactor
    unixns := int64(timeToConvert  % nsToSecFactor)

    time := time.Unix(unixsec, unixns)
    fmt.Println(time.Local())
}

注意:我已經用一些數字對此進行了檢查,但建議您在依賴它之前進行進一步測試。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM