Go 为什么是时间。因为在Windows上返回负持续时间?

Go 为什么是时间。因为在Windows上返回负持续时间?,go,time,Go,Time,我一直在尝试使用go,发现windows上有一些奇怪的行为。如果我通过解析特定格式的时间字符串来构造时间对象,然后使用诸如time.Since()之类的函数,我会得到负的持续时间 代码示例: package main import ( "fmt" "time" "strconv" ) func convertToTimeObject(dateStr string) time.Time { layout := "2006-01-02T15:04:05.000Z"

我一直在尝试使用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 Playerd上运行它,您将得到预期的持续时间
Duration in seconds:30

但是,在Windows上,使用Go 1.10.3运行同一段代码会给出
持续时间(秒):-19769

我已经在这上面撞了好几个小时了。关于我可能缺少的东西有什么帮助吗? 从现在起,我得到的唯一线索是,当go的
time
包去计算两个时间对象的秒数(
time.now()
和我解析的时间对象)时,其中一个具有属性
hasMonotonic
,另一个没有,这导致go计算两个时间对象的秒数相差很大


我不是当时的专家,所以希望能得到一些帮助。我本来打算为Go提交一个bug,但我想在这里向专家询问是否有明显的遗漏。

我想我已经找到了代码片段奇怪行为的原因,并可以提供解决方案。有关决议案文如下:

since
返回t之后经过的时间。它是时间的简写形式

但是:

now
返回当前本地时间

这意味着您正在格式化
timeOlder
,并从未格式化的本地时间中减去它。这当然会导致意想不到的行为。一个简单的解决方案是根据您的格式解析本地时间,然后再从中减去
timeOlder

在我的机器上运行的解决方案(不过,举一个游乐场的例子可能没有多大意义):

产出:

duration in seconds: 14430
duration: 30s

非常接近5.5小时。这可能会把你带到印度,注意当地时间与UTC的对比。你的布局不完整。A
Z
后面应该是
07
0700
07:00
中的一个。看。@HansPassant啊,是的,这是有道理的。这解释了为什么它在我的Linux机器中工作(时区设置为UTC)。然而,在我看来,这不应该发生。见我对彼得的答复。另外,在您的帮助下,我知道这不是一个仅限Windows的问题,您是否建议更改问题的标题?SFO新手。@Peter-时间在,其中单数Z表示它是UTC时间,与GMT的偏移量为零。从这个意义上说,布局确实有时区的上下文,但可能与Go不兼容?
Z
如果没有偏移格式,则会像在UTC中一样打印时间值:。在打印之前,它实际上不会将其转换为UTC。
duration in seconds: 14430
duration: 30s