【问题标题】:How to parse a milliseconds-since-epoch timestamp string in Go?如何在 Go 中解析毫秒以来的时间戳字符串?
【发布时间】:2012-10-28 23:31:58
【问题描述】:

我有一个自纪元以来毫秒的字符串(它最初来自java.lang.System.currentTimeMillis() 调用)。在 Go 中将此字符串转换为人类可读的时间戳字符串的正确方法是什么?

查看the time package 我看到了Parse 函数,但布局似乎都是基于正常时区的时间。一旦进入 Time 对象,我可以使用Format(Time.Stamp) 来获得我想要的输出,但我不清楚如何将字符串放入 Time 对象。

【问题讨论】:

    标签: string datetime go


    【解决方案1】:

    格式字符串不支持从纪元开始的毫秒数,所以需要手动解析。例如:

    func msToTime(ms string) (time.Time, error) {
        msInt, err := strconv.ParseInt(ms, 10, 64)
        if err != nil {
            return time.Time{}, err
        }
    
        return time.Unix(0, msInt*int64(time.Millisecond)), nil
    }
    

    查看http://play.golang.org/p/M1dWGLT8XE 以现场体验示例。

    【讨论】:

    • 您的解决方案有效,但它利用了time.Unix 适应纳秒范围的值。您正在将毫秒转换为纳秒,但忽略了您应该真正将毫秒转换为秒和剩余的纳秒。这是您的解决方案的改编版:play.golang.org/p/XKHNPkSqgx.
    • 为什么要进行更多难以阅读的工作,而当 stdlib 为您完成时您可能会出错?来自文档:It is valid to pass nsec outside the range [0, 999999999].golang.org/pkg/time/#Unix
    • @StephenWeinberg 因为2**63-1纳秒只有292.3年。因此,如果出于任何原因,您希望处理 1677 之前或 2262 之后的日期,则应转换为秒 + 纳秒,而不仅仅是纳秒。当然,OP 说他的价值来自于 Java currentTimeMillis,所以除非他的软件在 300 年后仍然会被使用……;是的,这可能不太可能。不过,我认为仍然值得关注。
    • 当我在一个完整的纪元时间内使用它时。 0001-01-01 00:00:00 +0000 UTC strconv.ParseInt: parsing "1352397861001.9878789": invalid syntax 这意味着我需要删除纳秒。
    • 无效的语法来自 ParseInt,它假定一个整数。如果您可以将输入转换为自纪元以来的纳秒数,则可以在 time.Unix 函数中使用它(替换msInt*int64(time.Millisecond))。
    【解决方案2】:

    使用time.Unix(ms/1000, 0) 就可以了。

    首先使用众所周知的关系 1 s = 1000 ms 将 ms-timestamp 转换为 unix-timestamp,然后将结果用作 time.Unix 函数的第一个参数

    【讨论】:

    • 我刚刚测试了这种方法,你最终会以这种方式失去精度。 play.golang.org/p/XWpS-PtRJrj 输出:时间 [2020-09-30 00:31:29.461 +0000 UTC],Time2 [2020-09-30 00:31:29 +0000 UTC]
    【解决方案3】:

    accepted answer 不适用于某些日期范围,无论是在未来太远还是在过去太远,因为只能使用 64 位(距纪元正负 300 年)描述有限的日期范围。

    这将适用于毫秒描述的整个范围:

    var Epoch = time.Unix(0, 0)
    
    func ParseMillisecondUnixTimestamp(s string) (time.Time, error) {
        ts, err := strconv.Atoi(s)
        if err != nil {
            return time.Time{}, err
        }
    
        return Epoch.Add(time.Duration(ts) * time.Millisecond), nil
    }
    

    【讨论】:

      【解决方案4】:

      2021 更新:您可以使用UnixMilli 从整数解析。这将改进接受的答案:

       func msToTime(ms string) (time.Time, error) {
          msInt, err := strconv.ParseInt(ms, 10, 64)
          if err != nil {
              return time.Time{}, err
          }
      
          return time.UnixMilli(msInt), nil
      }
      

      【讨论】:

      • 从 Go 1.17 开始提供此功能
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-06-05
      • 1970-01-01
      • 2019-08-01
      • 1970-01-01
      • 2012-06-16
      • 2013-08-25
      • 2010-10-16
      相关资源
      最近更新 更多