为了账号安全,请及时绑定邮箱和手机立即绑定

time.Sub() 返回 1 秒,尽管差异超过了几年

time.Sub() 返回 1 秒,尽管差异超过了几年

Go
炎炎设计 2022-05-18 14:47:55
我正在尝试编写一段代码,该代码将对由于同步引起的系统时间变化做出反应。这是一个在 goroutine 内部运行的相当简单的代码:var start, end time.Timevar start_ts, end_ts int64var diff_ts time.Durationvar diff time.Durationfor {    start = time.Now()    start_ts = start.Unix()    fmt.Printf("Now: => %v (%d);\n", start, start_ts)    time.Sleep(1 * time.Second)    end = time.Now()    end_ts = end.Unix()    fmt.Printf("New Now: %v (%d);\n", end, end_ts)    diff = end.Sub(start)    diff_ts = time.Duration(end_ts-start_ts) * time.Second    fmt.Printf("Measured time duration: %v (%v) %f (%f)\n", diff, diff_ts, diff.Seconds(), diff_ts.Seconds())}我的问题是,当我在另一个控制台中更改系统时间时,时间读取正确,但是“原始”时差不正确,我不得不求助于手动构建时差。以下是日志的摘录:Now: => 2020-02-26 12:29:42.778827718 +0000 UTC m=+21.776791756 (1582720182);New Now: 2017-01-01 01:02:03.391215325 +0000 UTC m=+22.777003266 (1483232523);Measured time duration: 1.00021151s (-27635h27m39s) 1.000212 (-99487659.000000)diff 对象为什么会返回 1 秒,即使差异明显大于那?
查看完整描述

1 回答

?
GCT1015

TA贡献1827条经验 获得超4个赞

go 的时间包同时使用“挂钟”(您要更改的内容)和单调时钟。从文档

操作系统提供了一个“挂钟”,它会随着时钟同步的变化而变化,而“单调时钟”则不会。一般规则是挂钟是用来报时的,而单调钟是用来测量时间的。而不是拆分 API,在这个包中 time.Now 返回的时间包含挂钟读数和单调时钟读数;后来的计时操作使用挂钟读数,但后来的时间测量操作,特别是比较和减法,使用单调时钟读数。

[...]

如果时间 t 和 u 都包含单调时钟读数,则仅使用单调时钟读数执行操作 t.After(u)、t.Before(u)、t.Equal(u) 和 t.Sub(u) ,忽略挂钟读数。

这是专门设计用于在发生时钟同步(ntp 等)时防止异常的应用程序行为(并将时钟推回)。go 的 time 包确保单调时钟读数总是向前移动(在比较或减法运算时)。


查看完整回答
反对 回复 2022-05-18
  • 1 回答
  • 0 关注
  • 132 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号