英文:
time comparison fails for identical times using two different location objects?
问题
我期望time.Now().In(location)
返回的对象在相同的时刻进行比较时是相同的,即使location
对象是不同的,只要这些location
对象是使用相同的name
字符串创建的。
为什么这个期望没有成立?
package main
import (
"fmt"
"time"
"log"
)
func main() {
const USPacificTimeZone = "US/Pacific"
location, err := time.LoadLocation(USPacificTimeZone)
if err != nil {
log.Fatal(fmt.Sprintf("Couldn't load timezone: %v", err))
}
// 与上面的location完全相同,只是一个新的实例
location2, err := time.LoadLocation(USPacificTimeZone)
if err != nil {
log.Fatal(fmt.Sprintf("Couldn't load timezone: %v", err))
}
now := time.Now()
fmt.Printf("使用相同的location对象的时间:%v\n",
now.In(location) == now.In(location))
// 输出:使用相同的location对象的时间:true
// 使用(相同的)location2 导致时间不同???
fmt.Printf("使用不同的location对象的时间:%v\n",
now.In(location) == now.In(location2))
// 输出:使用不同的location对象的时间:false
}
英文:
I am expecting time.Now().In(location)
objects to compare as identical if they are for the same moment, even though the location
objects are different, as long as the location
objects are created using the same name
string.
Why doesn't that expectation hold?
package main
import (
"fmt"
"time"
"log"
)
func main() {
const USPacificTimeZone = "US/Pacific"
location, err := time.LoadLocation(USPacificTimeZone)
if err != nil {
log.Fatal(fmt.Sprintf("Couldn't load timezone: %v", err))
}
// Exactly the same as location above, just a new instance
location2, err := time.LoadLocation(USPacificTimeZone)
if err != nil {
log.Fatal(fmt.Sprintf("Couldn't load timezone: %v", err))
}
now := time.Now()
fmt.Printf("Times using same location object: %v\n",
now.In(location) == now.In(location))
// prints: Times using same location object: true
// Using (the identical) location2 causes the times to be different???
fmt.Printf("Times using different location objects: %v\n",
now.In(location) == now.In(location2))
// prints: Times using different location objects: false
}
答案1
得分: 4
使用Equal方法来比较时间点:
fmt.Printf("Times using different location objects: %v\n",
now.In(location).Equal(now.In(location2))) // 输出 true
Time类型文档描述了使用==
比较Time值的陷阱:
注意,Go的
==
运算符不仅比较时间点,还比较时区和单调时钟读数。因此,Time值在用作映射或数据库键之前,应确保所有值都设置了相同的时区,可以通过使用UTC或Local方法来实现,并通过设置t = t.Round(0)
来去除单调时钟读数。一般来说,优先使用t.Equal(u)
而不是t == u
,因为t.Equal
使用了最准确的比较方法,并正确处理了只有一个参数具有单调时钟读数的情况。
英文:
Use the Equal method to compare instants in time:
fmt.Printf("Times using different location objects: %v\n",
now.In(location).Equal(now.In(location2))) // prints true
The Time type documentation describes the pitfalls of comparing Time values with ==
:
> Note that the Go == operator compares not just the time instant but also the Location and the monotonic clock reading. 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, and that the monotonic clock reading has been stripped by setting t = t.Round(0). In general, prefer t.Equal(u) to t == u, since t.Equal uses the most accurate comparison available and correctly handles the case when only one of its arguments has a monotonic clock reading.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论