UTC() 调用在 rand.Seed(time.Now().UTC().UnixNano()) 中是多余的吗?

Lon*_*ner 0 time timezone utc go random-seed

网上很多例子都是rand.Seed(time.Now().UTC().UnixNano())用来初始化伪随机数生成器种子的。

我看到如果我省略UTC()调用,它仍然可以正常工作。

Unix(或 UnixNano)时间无论如何是自纪元以来的秒数(或毫秒),即 1970-01-01 00:00:00.000000000 UTC。Unix 或 UnixNano 时间无论如何与时区无关。

以下面的代码为例:

package main

import (
        "fmt"
        "time"
)

func main() {
        t := time.Now()
        fmt.Println(t.UnixNano())
        fmt.Println(t.UTC().UnixNano())
}
Run Code Online (Sandbox Code Playgroud)

所以我的问题是:UTC()打电话是否有任何目的,或者省略UTC()电话而只是打电话是否安全rand.Seed(time.Now().UnixNano())

g.t*_*obi 5

可以肯定地说,您可以UTC()在使用时省略UnixNano()

UTC()先看 in time.go:1107的代码:

// UTC returns t with the location set to UTC.
func (t Time) UTC() Time {
    t.setLoc(&utcLoc)
    return t
}
Run Code Online (Sandbox Code Playgroud)

它只设置当前时间的位置。

现在,根据In()time.go 文件中对方法的评论,位置信息仅用于“显示目的”。参见 time.go:1119:

// In returns a copy of t representing the same time instant, but
// with the copy's location information set to loc for display
// purposes.
//
// In panics if loc is nil.
func (t Time) In(loc *Location) Time {
    if loc == nil {
        panic("time: missing Location in call to Time.In")
    }
    t.setLoc(loc)
    return t
}
Run Code Online (Sandbox Code Playgroud)

只有在必须显示时间时才使用位置:

// abs returns the time t as an absolute time, adjusted by the zone offset.
// It is called when computing a presentation property like Month or Hour.
func (t Time) abs() uint64 {
    l := t.loc
    // Avoid function calls when possible.
    if l == nil || l == &localLoc {
        l = l.get()
    }
    sec := t.unixSec()
    if l != &utcLoc {
        if l.cacheZone != nil && l.cacheStart <= sec && sec < l.cacheEnd {
            sec += int64(l.cacheZone.offset)
        } else {
            _, offset, _, _ := l.lookup(sec)
            sec += int64(offset)
        }
    }
    return uint64(sec + (unixToInternal + internalToAbsolute))
}
Run Code Online (Sandbox Code Playgroud)

运行以下代码以查看差异。两者都基于相同的 UnixNano,只有小时变化,因为位置仅在打印之前应用:

var now = time.Now()
var utc = now.UTC()
fmt.Printf("now UnixNano: %d, Hour: %d, Minute: %d, Second: %d\n", now.UnixNano(), now.Hour(), now.Minute(), now.Second())
fmt.Printf("utc UnixNano: %d, Hour: %d, Minute: %d, Second: %d\n", utc.UnixNano(), utc.Hour(), utc.Minute(), utc.Second())

now UnixNano: 1595836999431598000, Hour: 10, Minute: 3, Second: 19
utc UnixNano: 1595836999431598000, Hour: 8, Minute: 3, Second: 19
Run Code Online (Sandbox Code Playgroud)