我使用time.Time
创建了time.Date()
。然后我计算1970/1/1 00:00:00.000000000
与那个时间之间的纳秒数。
然后我使用纳秒,然后使用time.Time
将它们转回time.Unix()
。
但是,如果我使用==
将重构时间与原始时间进行比较,则返回false。如果我减去这两次,结果持续时间为0.如果我使用time.Equal()
比较这两次,则返回true。
如果我使用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
}
为什么重构时间与原始时间相比会返回false?
答案 0 :(得分:5)
time.Time
是struct
。当您尝试将它们与==
进行比较时,请引用Spec: Comparison operator:
如果所有字段都具有可比性,则结构值具有可比性。如果相应的非blank字段相等,则两个struct值相等。
因此t1 == t2
将比较2个Time
结构值的所有字段。 Time
结构不仅包含自基准时间以来的第二个和纳秒,它还包含作为指针的位置:*Location
,因此==
也将比较位置字段。比较指针:
指针值具有可比性。如果两个指针值指向同一个变量或两者都具有值
nil
,则它们相等。不同zero-size变量的指针可能相等也可能不相等。
这就是为什么将时间与==
进行比较会得到false
结果:即使地址不同,2个地点也可能表示相同的位置,这就是您的情况。
证明这一点:
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 ==运算符不仅会比较时刻,还会比较位置。因此,如果没有首先保证为所有值设置了相同的Location,则不应将Time值用作映射或数据库键,这可以通过使用UTC或Local方法来实现。
如果t1
和t2
也包含相同的*Location
指针,即使与==
运算符进行比较,它们也会相等。这可以通过调用Time.UTC()
或Time.Local()
方法来确保,这些方法返回time.Time
值,其中使用相同的位置指针(*Location
)。或者使用设置指定位置指针的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上尝试。