【问题标题】:How to parse unix timestamp to time.Time如何将 unix 时间戳解析为 time.Time
【发布时间】:2014-09-19 03:52:56
【问题描述】:

我正在尝试解析 Unix timestamp,但出现超出范围错误。这对我来说真的没有意义,因为布局是正确的(如 Go 文档中所示):

package main

import "fmt"
import "time"

func main() {
    tm, err := time.Parse("1136239445", "1405544146")
    if err != nil{
        panic(err)
    }

    fmt.Println(tm)
}

Playground

【问题讨论】:

    标签: go time unix-timestamp


    【解决方案1】:

    time.Parse 函数不使用 Unix 时间戳。相反,您可以使用strconv.ParseInt 将字符串解析为int64 并使用time.Unix 创建时间戳:

    package main
    
    import (
        "fmt"
        "time"
        "strconv"
    )
    
    func main() {
        i, err := strconv.ParseInt("1405544146", 10, 64)
        if err != nil {
            panic(err)
        }
        tm := time.Unix(i, 0)
        fmt.Println(tm)
    }
    

    输出:

    2014-07-16 20:55:46 +0000 UTC
    

    游乐场: http://play.golang.org/p/v_j6UIro7a

    编辑:

    strconv.Atoi 更改为 strconv.ParseInt 以避免 32 位系统上的 int 溢出。

    【讨论】:

    • 知道为什么文档中没有这样的参考吗?他们甚至给出了 unix 时间戳布局作为布局示例。
    • 我猜这是因为 unix 时间戳不需要解析,因为它不是文本表示,而是时间的整数表示。你只是碰巧有一个整数值的字符串表示。并且在文档中提到 1136239445 可能只是为了澄清要用作参考时间的确切时间戳,而不是用作布局。
    • 使用strconv.ParseUint 会不会更好,因为负数无论如何都没有意义?
    • @Atmocreations: func Unix(sec int64, nsec int64) Time 接收 int64 值。此外,秒的负数非常有意义 - 它们描述了 1970 年之前的日期! :) 至于nsec,负值意味着从秒中删除那么多纳秒。
    • 我只想要日期和时间为“ 2014-07-16 20:55:46” 怎么可能实现?
    【解决方案2】:

    你可以直接使用time.Unix时间函数将unix时间戳转换为UTC

    package main
    
    import (
      "fmt"
      "time"
    )
    
    
    func main() {
        unixTimeUTC:=time.Unix(1405544146, 0) //gives unix time stamp in utc 
    
        unitTimeInRFC3339 :=unixTimeUTC.Format(time.RFC3339) // converts utc time to RFC3339 format
    
        fmt.Println("unix time stamp in UTC :--->",unixTimeUTC)
        fmt.Println("unix time stamp in unitTimeInRFC3339 format :->",unitTimeInRFC3339)
    }
    

    输出

    unix time stamp in UTC :---> 2014-07-16 20:55:46 +0000 UTC
    unix time stamp in unitTimeInRFC3339 format :----> 2014-07-16T20:55:46Z
    

    签到 Go Playground:https://play.golang.org/p/5FtRdnkxAd

    【讨论】:

    • time.Unix() 被记录为返回本地时间。因此,此答案中的 unixTimeUTC 并不总是提供 UTC 时区的时间。仅当本地时区对应于 UTC 时。
    • @Dr.Jan-PhilipGehrcke:我想知道这最终是否重要。 time.Unix() 会将时间解析为某个时区的时间(带有时区信息)。然后它可以在任何地方重复使用(例如转换为给定的 TZ)。的确,在这种情况下,变量名可能并不幸运。
    【解决方案3】:

    分享一些我为日期创建的函数:

    请注意,我想获取特定位置的时间(不仅仅是 UTC 时间)。如果您想要 UTC 时间,只需删除 loc 变量和 .In(loc) 函数调用。

    func GetTimeStamp() string {
         loc, _ := time.LoadLocation("America/Los_Angeles")
         t := time.Now().In(loc)
         return t.Format("20060102150405")
    }
    func GetTodaysDate() string {
        loc, _ := time.LoadLocation("America/Los_Angeles")
        current_time := time.Now().In(loc)
        return current_time.Format("2006-01-02")
    }
    
    func GetTodaysDateTime() string {
        loc, _ := time.LoadLocation("America/Los_Angeles")
        current_time := time.Now().In(loc)
        return current_time.Format("2006-01-02 15:04:05")
    }
    
    func GetTodaysDateTimeFormatted() string {
        loc, _ := time.LoadLocation("America/Los_Angeles")
        current_time := time.Now().In(loc)
        return current_time.Format("Jan 2, 2006 at 3:04 PM")
    }
    
    func GetTimeStampFromDate(dtformat string) string {
        form := "Jan 2, 2006 at 3:04 PM"
        t2, _ := time.Parse(form, dtformat)
        return t2.Format("20060102150405")
    }
    

    【讨论】:

    • 删除 .In(loc) 让我有时间在 -0400 EDT。用.In(time.UTC) 替换它给了我UTC 时间。
    【解决方案4】:

    根据go documentation,Unix 返回一个本地时间。

    Unix 返回与给定 Unix 时间对应的本地时间

    这意味着输出将取决于您的代码运行所在的机器,这通常是您需要的,但有时,您可能希望使用 UTC 值。

    为此,我调整了 snippet 以使其返回 UTC 时间:

    i, err := strconv.ParseInt("1405544146", 10, 64)
    if err != nil {
        panic(err)
    }
    tm := time.Unix(i, 0)
    fmt.Println(tm.UTC())
    

    这在我的机器上打印(在 CEST 中)

    2014-07-16 20:55:46 +0000 UTC
    

    【讨论】:

      【解决方案5】:

      我在时间戳为 float64 的情况下进行了大量日志记录,并使用此函数将时间戳作为字符串获取:

      func dateFormat(layout string, d float64) string{
          intTime := int64(d)
          t := time.Unix(intTime, 0)
          if layout == "" {
              layout = "2006-01-02 15:04:05"
          }
          return t.Format(layout)
      }
      

      【讨论】:

        【解决方案6】:

        这是一个老问题,但我注意到缺少实用的答案。

        例如,我们正在使用 MavLink 协议,我们需要处理带有structure defined here 的消息。

        如果我们有这个数据结构:

        Field Name Type Units Description
        time_boot_ms uint64_t ms Timestamp (time since system boot).
        press_abs float hPa Absolute pressure
        press_diff float hPa Differential pressure 1
        temperature int16_t cdegC Absolute pressure temperature
        temperature_press_diff ** int16_t cdegC Differential pressure temperature (0, if not available). Report values of 0 (or 1) as 1 cdegC.

        因此,我们会收到持续更新,我们需要使用 time_boot_ms 作为参考来处理这些更新,以便将它们插入数据库并与其他消息同步。

        我们能做什么?

        正如我们所注意到的,时间以毫秒为单位,每个对 Go 有一定经验的人都知道,由于某些未知原因,将毫秒分辨率的 Unix timestamp 转换为太复杂了time.Time。内置的time.Unix()函数只支持秒和纳秒精度。

        我们如何获得毫秒精度?

        好吧,我们可能会等到他们发布 Go1.7 版本,或者我们必须将毫秒乘以纳秒,或者将它们分成秒和纳秒。

        让我们实现第二个想法,将其分为秒和纳秒:

        unixUTCtime := time.Unix(ms/int64(1000), (ms%int64(1000))*int64(1000000))
        

        现在我们可以将它封装在 func 中,并像这样在我们的 main 中使用它:

        package main
        
        import (
            "fmt"
            "time"
        )
        
        const msInSecond int64 = 1e3
        const nsInMillisecond int64 = 1e6
        
        // UnixToMS Converts Unix Epoch from milliseconds to time.Time
        func UnixToMS (ms int64) time.Time {
            return time.Unix(ms/msInSecond, (ms%msInSecond)*nsInMillisecond)
        }
        
        
        func main() {
            unixTimes := [...]int64{758991688, 758992188, 758992690, 758993186}
            var unixUTCTimes []time.Time
            for index, unixTime := range unixTimes {
                unixUTCTimes = append(unixUTCTimes, UnixToMS(unixTime))
                if index > 0 {
                    timeDifference := unixUTCTimes[index].Sub(unixUTCTimes[index-1])
                    fmt.Println("Time difference in ms :--->", timeDifference)
                }
            }
        }
        

        输出将是:

        Time difference in ms :---> 500ms
        Time difference in ms :---> 502ms
        Time difference in ms :---> 496ms
        

        Check in Go Playground

        【讨论】:

          猜你喜欢
          • 2017-02-20
          • 2021-06-07
          • 2021-12-17
          • 1970-01-01
          • 2020-05-27
          • 1970-01-01
          • 2015-04-08
          • 2013-07-22
          • 2020-09-16
          相关资源
          最近更新 更多