如何将unix时间戳解析为time.Time

hey*_*hey 104 time go unix-timestamp

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

package main

import "fmt"
import "time"

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

    fmt.Println(tm)
}
Run Code Online (Sandbox Code Playgroud)

操场

ANi*_*sus 185

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)
}
Run Code Online (Sandbox Code Playgroud)

输出:

2014-07-16 20:55:46 +0000 UTC
Run Code Online (Sandbox Code Playgroud)

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

编辑:

从改变strconv.Atoistrconv.ParseInt,以避免在32个系统INT溢出.

  • @Atmocreations:`func Unix(sec int64,nsec int64)Time`收到`int64`值.此外,sec的负数非常有意义 - 它们描述了1970年之前的日期!:)对于`nsec`,负值意味着从秒中移除那么多纳秒. (6认同)
  • 使用`strconv.ParseUint`不是更好,因为负数无论如何都没有意义吗? (4认同)
  • 知道为什么文档中没有这样的参考吗?他们甚至将 Unix 时间戳布局作为布局示例。 (3认同)
  • 我想这是因为 unix 时间戳不需要解析,因为它不是文本表示,而是时间的整数表示。你碰巧有一个整数值的字符串表示。并且在文档中提到 1136239445 可能只是为了澄清将哪个确切的时间戳用作参考时间,而不是将其用作布局。 (2认同)

小智 9

你可以直接使用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)
}
Run Code Online (Sandbox Code Playgroud)

}

产量

unix time stamp in UTC :---> 2014-07-16 20:55:46 +0000 UTC
unix time stamp in unitTimeInRFC3339 format :----> 2014-07-16T20:55:46Z
Run Code Online (Sandbox Code Playgroud)

登记Go Playground:https://play.golang.org/p/5FtRdnkxAd

  • `time.Unix()` 被记录为返回本地时间。因此,此答案中的“unixTimeUTC”并不总是提供 UTC 时区的时间。仅当本地时区对应于 UTC 时。 (2认同)

Adi*_*Adi 5

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

请注意,我想获取特定位置的时间(不仅仅是 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")
}
Run Code Online (Sandbox Code Playgroud)


Teo*_*cci 5

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

例如,我们正在使用 MavLink 协议,我们需要处理具有此处定义的结构的消息。

如果我们有这样的数据结构:

字段名称 类型 单位 描述
启动时间毫秒 uint64_t 多发性硬化症 时间戳(自系统启动以来的时间)。
按_abs 漂浮 百帕 绝对压力
按_差异 漂浮 百帕 压差1
温度 int16_t cdC 绝对压力温度
温度压差 ** int16_t cdC 压差温度(0,如果不可用)。将 0(或 1)值报告为 1 cdegC。

因此,我们收到不断的更新,我们需要使用作为time_boot_ms引用来处理这些更新,将它们插入到数据库中并将它们与其他消息同步。

我们可以做什么?

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

我们怎样才能达到毫秒级的精度呢?

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

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

unixUTCtime := time.Unix(ms/int64(1000), (ms%int64(1000))*int64(1000000))
Run Code Online (Sandbox Code Playgroud)

现在我们可以将它封装在 a 中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)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

输出将是:

Time difference in ms :---> 500ms
Time difference in ms :---> 502ms
Time difference in ms :---> 496ms
Run Code Online (Sandbox Code Playgroud)

打卡Go游乐场

更新

从版本开始1.7,现在提供毫秒分辨率,可以使用time.UnixMilligo函数将表示为int64数字的 Unix 时间转换为 Time 类型(纳秒精度) ,也可以使用UnixMilli函数将 Time 转换为毫秒精度。这是他们的实现:

func Unix(sec int64, nsec int64) Time {
    if nsec < 0 || nsec >= 1e9 {
        n := nsec / 1e9
        sec += n
        nsec -= n * 1e9
        if nsec < 0 {
            nsec += 1e9
            sec--
        }
    }
    return unixTime(sec, int32(nsec))
}


func UnixMilli(msec int64) Time {
    return Unix(msec/1e3, (msec%1e3)*1e6)
}

func (t Time) UnixMilli() int64 {
    return t.unixSec()*1e3 + int64(t.nsec())/1e6
}
Run Code Online (Sandbox Code Playgroud)

如何使用这个 Teo?

非常简单,只需修改我们示例的先前实现中的这一行即可:

unixUTCTimes = append(unixUTCTimes, UnixToMS(unixTime))
Run Code Online (Sandbox Code Playgroud)

用这个代码:

unixUTCTimes = append(unixUTCTimes, time.UnixMilli(unixTime))
Run Code Online (Sandbox Code Playgroud)

不需要其他函数,直接调用即可time.UnixMilli(unixTime)。检查这里的操场


Jas*_*onw 5

对于 millis unix 时间戳精度,在 go1.18 中

    i, err := strconv.ParseInt("1652084489543", 10, 64)
    if err != nil {
        panic(err)
    }
    tm := time.UnixMilli(i)
    fmt.Println(tm)

Run Code Online (Sandbox Code Playgroud)