go 1.9 之后,给Time增加了 Monotonic 部分。

系统提供了wall time 和 monotonic 时间。
其中wall time会根据时间校准而改变,而monotonic不会。

举个例子。
你写了一个日志收集程序,每10秒把收到的日志汇报给流式收集系统。
但是你的机器事件比真实时间快了1分钟。

1
2
3
now := time.Now()
<-now.After(time.Second*10):
// do sth

假如得到now的时间以后,机器与外部时间进行了一步同步,把本机实际时间调慢1分钟,那么程序将会在第二行卡上70秒。
这会导致本地日志队列可能会爆仓。

与Duration相关的时间操作,譬如time.Since(start), time.Until(deadline), and time.Now().Before(deadline)等,对于时间重置非常敏感,所以它们需要参考 Monotonic 时间。

而如果时间是为了打印,或者start time/deadline time是外界传入的,那么 monotonic 时间将会是一个干扰。 此时应该使用 t = t.Round(0) 排除 monotonic。