我一直在努力工作,并且在 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()
和我解析的时间对象)的秒数时,其中一个具有属性{{1 }}却没有,
我不是及时的专家,所以希望能有所帮助。我本来打算为Go提交一个错误,但是我想从专家那里询问是否有明显的东西我可能会丢失。
答案 0 :(得分:0)
我想我已经弄清楚了您的代码段异常行为的原因是什么,并且可以提供解决方案。相关的docs内容如下:
since
返回自t以来经过的时间。是时间的简写。Now()。Sub(t)。
但是:
now
返回当前本地时间。
这意味着您正在格式化timeOlder
并将其从未格式化的本地时间中减去。那当然会导致意外的行为。一种简单的解决方案是根据您的格式解析本地时间,然后再从中减去timeOlder
。
可以在我的机器上运行的解决方案(不过,给出一个操场示例可能没有多大意义):
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