当前位置: 首页 > 面试题库 >

为什么与==相比,具有相同日期和时间的2个时间结构返回false?

狄宇
2023-03-14
问题内容

我有一个time.Time使用创建的time.Date()。然后,我计算出1970/1/1 00:00:00.000000000与该时间之间的纳秒数。

然后,我花了十亿分之一秒,然后将它们重新变成了time.Timeuse time.Unix()

但是,如果我使用来比较重构时间和原始时间==,则返回false。如果我减去这2次,则得到的持续时间为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
}

为什么重组时间与原始时间相比返回假?


问题答案:

time.Time是一个struct。当您尝试将它们与进行比较时==,请引用“
规范:比较运算符”:

如果结构的所有字段都是可比较的,则它们的值是可比较的。如果两个结构值对应的非空白字段相等,则它们相等。

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

指针值是可比较的。如果两个指针值指向同一个变量或都具有value,则它们相等nil。指向不同零大小变量的指针可以相等或可以不相等。

这就是为什么将时间与进行比较从而==得出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
==运算符不仅会比较时间瞬间,还会比较位置。因此,在不首先确保已为所有值设置相同的位置的情况下,不应将时间值用作地图或数据库键,这可以通过使用UTC或Local方法来实现。

如果t1t2也包含相同的*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上尝试一下。



 类似资料:
  • 我在生产中遇到了一个奇怪的问题,在操作了5年多后只发生过一次。我们发现,PSPermGen和“real”持续时间远远高于User+SYS时间。2016年2月4日,PSPermGen花了38.96秒,而以前的运行是0.2-0.3秒,并且没有释放内存。当User+SYS为0.3-0.4秒时,实时时间需要40秒,与以前的运行相比,这是异常高的。完全的GC并不经常发生,我也没有观察到任何与GC相关的错误。

  • 问题内容: 我有一个包含表的MySQL数据库。 但是,我找不到在Java中将其作为Java中某种对象返回的方法。 我可以打电话给它,它会返回,但这并不好,因为没有办法比较字符串上的日期等。 我也可以打电话,但这根本不返回时间。 问题答案: 您需要使用Thomas的注释中建议的getTime()或getTimestamp()方法。举个例子… 说出要查询的表格,如下所示: 您可以这样做: 如果要使用J

  • 本文向大家介绍Java 日期与时间API相关用法总结,包括了Java 日期与时间API相关用法总结的使用技巧和注意事项,需要的朋友参考一下 一、时间和日期 在系统开发中,日期与时间作为重要的业务因素,起到十分关键的作用,例如同一个时间节点下的数据生成,基于时间范围的各种数据统计和分析,集群节点统一时间避免超时等。 在时间和日期中有几个关键概念: 日期:通常年月日的组合表示当前日期。 时间:通常时分

  • > -返回类型是实体和 -返回类型为实体 过程1需要一个额外的步骤,使用optional.get()从optional中获取实体。有什么不同吗?你推荐哪一种?

  • 我有个约会‘2019-05-08t 22:15:00-0400’。我想将这个日期与当前的日期和时间进行比较。如果上述日期和时间小于当前日期和时间,那么我必须做些什么。 我的代码是:- 但它返回 false 。