为什么与==相比,具有相同日期和时间的2次结构返回false? [英] Why do 2 time structs with the same date and time return false when compared with ==?

查看:152
本文介绍了为什么与==相比,具有相同日期和时间的2次结构返回false?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用 time.Date()创建了 time.Time 。然后计算 1970/1/1 00:00:00.000000000 和那段时间之间的纳秒数。



然后我用纳秒将它们变回 time.Time ,使用 time.Unix()



但是,如果我使用 == 比较重新组合的时间,它将返回false。如果我减去这两次,结果的持续时间为0.如果我使用 time.Equal()比较这两次,它将返回true。



如果我使用 time.date()创建另一次与第一次相同的值,使用 == 来比较这个新时间和原始时间的结果是真实的。



这是演示这个的代码( Golang Playground ):

 包主要

导入(
fmt
时间


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()//计算从1970/1/1到纳秒的数量

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 。当您尝试将它们与 == 比较时,从规格:比较运算符


如果所有字段都具有可比性,则结构值具有可比性。如果其相应的非空白字段相同,则两个结构值相等。


所以 t1 == t2 会比较2 时间的所有字段结构值。 Time 结构不仅包含自基时以来的秒和纳秒,还包含作为指针的位置: * Location ,所以 == 也会比较位置字段。比较指针:


指针值具有可比性。如果两个指针的值指向同一个变量,或者两者的值都小于code> nil ,则两个指针值相等。指向不同零大小的变量可能相等,也可能不相等。


这就是为什么比较时间与 == 给出 false code>结果:即使地址不同,2个地点也可能表示同一地点,这是您的情况。

为了证明这一点:

  fmt.Println(Locations:,t1.Location(),t2.Location())
fmt.Printf(定位指针:%p%p \ n,t1.Location(),t2.Location())
fmt.Println(Locations equal:,t1.Location()== t2.Location() )

输出:

 位置:UTC UTC 
位置指针:0x1e2100 0x1e6de0
位置相等:false

记录在 time.Time


注Go ==运算符不仅比较时间而且还比较时间 位置。因此,如果不首先确保已为所有值设置了相同的位置,则可以通过使用UTC或Local方法来实现时间值,而不应将其作为地图或数据库密钥。


blockquote>

如果 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)//现在是true
fmt.Println(t1.Equal(t2))//仍然是
$ b

输出:

$ p $ 位置:UTC UTC
位置指针:0x1e2100 0x1e2100
位置等于:真


试试去游乐场


I have a time.Time created using time.Date(). I then calculate the number of nanoseconds between 1970/1/1 00:00:00.000000000 and that time.

I then take the nanoseconds and turn them back into a time.Time using time.Unix().

However, if I compare the reconstituted time with the original using ==, it returns false. If I subtract these 2 times, the resulting duration is 0. If I compare these 2 times using time.Equal(), it returns true.

If I create another time using time.Date() with the same values as the first time, using == to compare this new time and the original time results in a true.

This is the code that demonstrates this (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
}

Why does the reconstituted time return false when compared with the original time?

解决方案

time.Time is a struct. When you try to compare them with ==, quoting from the Spec: Comparison operator:

Struct values are comparable if all their fields are comparable. Two struct values are equal if their corresponding non-blank fields are equal.

So t1 == t2 will compare all the fields of the 2 Time struct values. The Time struct contains not just the second and nanosecond since a base time, it also contains the location as a pointer: *Location, so == will also compare the location fields. Comparing pointers:

Pointer values are comparable. Two pointer values are equal if they point to the same variable or if both have value nil. Pointers to distinct zero-size variables may or may not be equal.

And this is why comparing the times with == gives a false result: 2 locations may denote the same location even if their address is different, and this is your case.

To prove this:

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())

Output:

Locations: UTC UTC
Location pointers: 0x1e2100 0x1e6de0
Locations equal: false

This is documented in time.Time:

Note that the Go == operator compares not just the time instant but also the Location. Therefore, Time values should not be used as map or database keys without first guaranteeing that the identical Location has been set for all values, which can be achieved through use of the UTC or Local method.

If t1 and t2 would also contain the same *Location pointer, they would be equal even if compared with the == operator. This can be ensured by calling Time.UTC() or Time.Local() method on them which returns a time.Time value where the same location pointer (*Location) is used. Or by using the Time.In() method which will set the specified location pointer (after the proper conversion), e.g.:

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

Output:

Locations: UTC UTC
Location pointers: 0x1e2100 0x1e2100
Locations equal: true
true
true

Try it on the Go Playground.

这篇关于为什么与==相比,具有相同日期和时间的2次结构返回false?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆