我一直在尝试使用 go,并在 windows 上发现了一些奇怪的行为。如果我通过解析特定格式的时间字符串构造时间对象,然后使用 time.Since()
等函数,我会得到负持续时间。
代码示例:
package main
import (
"fmt"
"time"
"strconv"
)
func convertToTimeObject(dateStr string) time.Time {
layout := "2006-01-02T15:04:05.000Z"
t, _:= time.Parse(layout, dateStr)
return t
}
func main() {
timeOlder := convertToTimeObject(time.Now().Add(-30*time.Second).Format("2006-01-02T15:04:05.000Z"))
duration := time.Since(timeOlder)
fmt.Println("Duration in seconds: " + strconv.Itoa(int(duration.Seconds())))
}
如果您在 Linux 或 Go Playground 上运行它 link ,您得到的结果为 Duration in seconds: 30
,这是预期的。
但是,在 Windows 上,使用 Go 1.10.3 运行同一段代码会得到 Duration in seconds: -19769
。
我已经为此苦苦思索了几个小时。对我可能遗漏的东西有什么帮助吗?
从现在开始我唯一的线索是,当 go 的 time
包去计算两个时间对象(time.Now()
和我解析的时间对象)的秒数时,其中一个具有 hasMonotonic
属性,而另一个没有,这导致两者计算的秒数大不相同。
我不是时间方面的专家,所以希望得到一些帮助。我本来打算为 Go 提交一个错误,但想在这里向专家询问是否有明显的我可能遗漏的东西。
最佳答案
我想我弄清楚了您的代码片段出现奇怪行为的原因,并且可以提供解决方案。相关docs阅读如下:
since
returns the time elapsed since t. It is shorthand for time.Now().Sub(t).
但是:
now
returns the current local time.
这意味着您正在格式化 timeOlder
并从未格式化的本地时间中减去它。这当然会导致意外行为。一个简单的解决方案是根据您的格式解析本地时间,然后再从中减去 timeOlder
。
一个在我的机器上运行的解决方案(尽管给出一个 playground 示例可能没有多大意义):
func convertToTimeObject(dateStr string) time.Time {
layout := "2006-01-02T15:04:05.000Z"
t, err := time.Parse(layout, dateStr)
// check the error!
if err != nil {
log.Fatalf("error while parsing time: %s\n", err)
}
return t
}
func main() {
timeOlder := convertToTimeObject(time.Now().Add(-30 * time.Second).Format("2006-01-02T15:04:05.000Z"))
duration := time.Since(timeOlder)
// replace time.Since() with a correctly parsed time.Now(), because
// time.Since() returns the time elapsed since the current LOCAL time.
t := time.Now().Format("2006-01-02T15:04:05.000Z")
timeNow := convertToTimeObject(t)
// print the different results
fmt.Println("duration in seconds:", strconv.Itoa(int(duration.Seconds())))
fmt.Printf("duration: %v\n", timeNow.Sub(timeOlder))
}
输出:
duration in seconds: 14430
duration: 30s
关于go - 为什么 time.Since 在 Windows 上返回负持续时间?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50970900/