1. 程式人生 > >翻譯下 golang package time

翻譯下 golang package time

# 關於 `package time`

個人體會:"wall clock" 可以理解為就是實際的時鐘,而 "monotonic clock" 則是程式內部的時鐘。
所以前者是用來獲取具體的時間,後者是用來計時的。
ps: 原文都是用 "monotonic clock reading",含意很明顯,就是讀取時間。

## 總覽

`package time` 提供了用於測量和顯示時間的功能。
日曆的計算,總是假定Gregorian日曆 - 無閏秒。

## Monotonic Clocks

作業系統同時提供了 "wall clock" 和 "monotonic clock",前者用於時鐘的同步,後者不是。
通用的做法是,"wall clock" 用於獲取時間,而 "monotonic clock" 則用於測量時間。
`time.Now()` 同時包含了 "wall clock" 和 "monotonic clock",想要讀取時間,就使用前者,想要測量時間、特殊的對比和相減,就使用後者。

例如,下面的程式碼是計算程式碼的執行耗時,大約總是20ms,無論 "wall clock"怎麼改變:
```golang
package time

start := time.Now()
//... operation that takes 20 milliseconds ...
t := time.Now()
elapsed := t.Sub(start)
```

在其他情況裡,例如 `time.Since(start)`、`time.Until(deadline)`以及`time.Now().Before(deadline)`,都是類似的,都與 "wall clock" 的改變無關。

本節的剩餘部分給出瞭如何使用"monotonic clock"的細節,但是,使用本package無需理解這些細節。

`time.Now()` 返回的 `Time`,包含了一個 `monotonic clock`。 而,如果 `Time t` 包含一個 "monotonic clock",那 `t.Add` 就可以同時給 "wall clock"和"monotonic clock"增加 duration - 以便計算結果。 因為 `t.AddDate(y, m, d)`、`t.Round(d)`和`t.Truncate(d)` 都是 "wall time"的計算,它們會從結果中去掉所有的 "monotonic clock"。因為 `t.In`、`t.Local`和`t.UTC` 都是使用它們的 "wall time" 結果,所以它們也會從結果中去掉所有的 "monotonic clock"。
去掉 "monotonic clock" 的權威做法是 `t = t.Round(0)`。

如果 `Time t`和 `Time u` 都包含 "monotonic clock",那麼操作 `t.After(u)`、`t.Before(u)`、`t.Equal(u)`以及`t.Sub(u)` 僅僅會使用 "monotonic clock",而忽略掉 "wall clock"。如果 `t`或`u` 有一個不包含 "monotonic clock",這些操作才會使用 "wall clock"。

在一些系統中,當計算機休眠的時候,"monotonic clock"會停止。在這種系統上,`t.Sub(u)`可能不會精確地反映`t`和`u`之間的時間。

因為 "monotonic clock" 的意義僅限於當前程序,所以由`t.GobEncode`、`t.MarshalBinary`、`t.MarshalJSON`和`t.MarshalText`序列化得到的內容會忽略掉 "monotonic clock",且 `t.Format` 也沒有提供相應的格式化。
類似地,使用 `time.Date`、`time.Parse`、`time.ParseInLocation`、`time.Unix`來構造,以及通過反序列化 `t.GobDecode`、`t.UnmarshalBinary`、`t.UnmarshalJSON`、`t.UnmarshalText`得到的時間,也不會包含 "monotonic clock" 。

注意,Go的 `==` 操作符,不僅會比較時間的`instant`,還會比較`Location`以及 "monotonic clock"。詳見 Time型別的文件,那裡有一個相等性測試的討論。

為了除錯方便,`t.String`包含了 "monotonic clock" - 如果存在的話。 如果 `t !=u ` 是因為不同的 "monotonic clock" 的話,可以通過 `t.String` 和 `u.String` 清楚地看到區別。