我有一个time.Time使用创建的time.Date()。然后,我计算出1970/1/1 00:00:00.000000000与该时间之间的纳秒数。
time.Time
time.Date()
1970/1/1 00:00:00.000000000
然后,我花了十亿分之一秒,然后将它们重新变成了time.Timeuse time.Unix()。
time.Unix()
但是,如果我使用来比较重构时间和原始时间==,则返回false。如果我减去这2次,则得到的持续时间为0。如果我使用进行比较time.Equal(),则返回true。
==
time.Equal()
如果我使用time.Date()与第一次相同的值来创建另一个时间,则使用==比较此新时间和原始时间将得出真。
这是演示此代码的代码(Golang Playground):
package main import ( "fmt" "time" ) func main() { t1 := time.Date(2016, 4, 14, 1, 30, 30, 222000000, time.UTC) base := time.Date(1970, 1, 1, 0, 0, 0, 0, t1.Location()) nsFrom1970 :=t1.Sub(base).Nanoseconds() // Calculate the number of nanoseconds from 1970/1/1 to t1 t2 := time.Unix(0, nsFrom1970) fmt.Println(t1) fmt.Println(t2) fmt.Println(t1.Sub(t2)) // 0 fmt.Println(t1 == t2) //false fmt.Println(t1.Equal(t2)) //true t3 := time.Date(2100, 2, 1, 21, 21, 21, 222000000, time.UTC) fmt.Println(t1 == t3) //true }
为什么重组时间与原始时间相比返回假?
time.Time是一个struct。当您尝试将它们与进行比较时==,请引用“ 规范:比较运算符”:
struct
如果结构的所有字段都是可比较的,则它们的值是可比较的。如果两个结构值对应的非空白字段相等,则它们相等。
因此t1 == t2将比较2个Timestruct值的所有字段。该Time结构不仅包含自基准时间以来的秒和纳秒,还包含位置作为指针:*Location,因此==还将比较位置字段。比较指针:
t1 == t2
Time
*Location
指针值是可比较的。如果两个指针值指向同一个变量或都具有value,则它们相等nil。指向不同零大小变量的指针可以相等或可以不相等。
nil
这就是为什么将时间与进行比较从而==得出false结果的原因:2个位置可能表示同一位置,即使它们的地址不同,这就是您的情况。
false
为了证明这一点:
fmt.Println("Locations:", t1.Location(), t2.Location()) fmt.Printf("Location pointers: %p %p\n", t1.Location(), t2.Location()) fmt.Println("Locations equal:", t1.Location() == t2.Location())
输出:
Locations: UTC UTC Location pointers: 0x1e2100 0x1e6de0 Locations equal: false
记录在time.Time:
请注意,Go ==运算符不仅会比较时间瞬间,还会比较位置。因此,在不首先确保已为所有值设置相同的位置的情况下,不应将时间值用作地图或数据库键,这可以通过使用UTC或Local方法来实现。
如果t1和t2也包含相同的*Location指针,则即使与==运算符进行比较,它们也将相等。可以通过在它们上调用Time.UTC()或Time.Local()方法来确保这一点,该方法返回使用time.Time相同位置指针(*Location)的值。或通过使用Time.In()将 设置 指定位置指针的方法(在正确转换之后),例如:
t1
t2
Time.UTC()
Time.Local()
Time.In()
t2 = t2.In(t1.Location()) fmt.Println("Locations:", t1.Location(), t2.Location()) fmt.Printf("Location pointers: %p %p\n", t1.Location(), t2.Location()) fmt.Println("Locations equal:", t1.Location() == t2.Location()) fmt.Println(t1 == t2) // Now true fmt.Println(t1.Equal(t2)) // Still true
Locations: UTC UTC Location pointers: 0x1e2100 0x1e2100 Locations equal: true true true
在Go Playground上尝试一下。