【问题标题】:Add nanoseconds from Win32 epoch to Go time将 Win32 纪元的纳秒添加到 Go 时间
【发布时间】:2020-01-25 00:31:42
【问题描述】:

我正在尝试使用 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 失败并出现溢出错误。

current_ts_2 在测试 2 中只给了我日期级别的分辨率。

理想情况下,我能够获得毫秒级的分辨率。有没有一种方法可以不溢出传递给.Add() 的 Duration 并仍然获得此分辨率?

【问题讨论】:

    标签: datetime go time


    【解决方案1】:

    这种转换需要处理一些巨大的数字。您的示例时间 13,224,382,394,716,547,600 太大而无法放入 int64(最大 9,223,372,036,854,775,807),但确实适合 unit64。

    你不能在处理这个时使用 time.Duration,因为这是一个 int64 纳秒计数;正如docs 所说,“该表示将最大可表示持续时间限制为大约 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())
    }
    

    注意:我已经用一些数字检查了这一点,但建议您在依赖它之前进行进一步测试。

    【讨论】:

      猜你喜欢
      • 2018-12-14
      • 2019-11-25
      • 2023-03-27
      • 2019-03-01
      • 2017-06-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-17
      相关资源
      最近更新 更多