Go1.20 中兩個關於 Time 的更新,終於不用背 2006-01-02 15:04:05 了!

煎魚 發表於 2022-11-22
Go

大家好,我是煎魚。

Go 語言中有一個東西是比較有特色的,那就是 time 標準庫,在各類與時間有關的場景都會常常用到,例如:定時/延遲任務、資料更新、時間比較。

官方 Demo 是一個計算時間差的樣例:

import "time"

func main() {
    start := time.Now()
    time.Sleep(time.Second)
    t := time.Now()
    elapsed := t.Sub(start)
    println(elapsed)
}

輸出結果:

1000000000

神秘的 2006-01-02 15:04:05

在社群反饋中,更虎的是以下這個樣例:

func main() {
    now := time.Now()
    v := now.Format("2006-01-02 15:04:05")
    println(v)
}

輸出結果:

2009-11-10 23:00:00

這時候大家會遇到幾個問題...最被常問的是 2006-01-02 15:04:05,這是隨便寫的時間點嗎,甚至還曾經有傳言說這是 Go 語言的誕生時間...

為什麼是這個時間點

實際上 2006-01-02 15:04:05 是一個參考時間的格式,也就是其它語言中 Y-m-d H:i:s 格式,在功能上用於時間的格式化處理和規範。

那為什麼是 2006-01-02 15:04:05 呢?其實這些 ”數字“ 是有意義的,每個佈局字串都是一個時間戳的表示,並非隨便寫的時間點。

可參見官方例子中的如下方式:

Jan 2 15:04:05 2006 MST
1   2  3  4  5    6  -7

我們也可以將其記憶為 2006 年 1 月 2 日 3 點 4 分 5 秒。

確實背不下來,快最佳化

雖然 Go 官方給出了一系列感覺很合理的解釋,也透過上面的方式試圖教會大家靠理解而不是靠純背把這個時間點格式規範給記下來...

現實是很殘酷的,母語不同,業務型別不同,不會經常用到 time 標準庫,很容易忘記具體數值。

大佬也分析了 Go modules 上的所有模組程式碼,發現這個日期時間點,使用的次數非常高頻:

排名頻率格式
175616time.RFC3339
223954time.RFC3339Nano
313312"2006-01-02 15:04:05"
412332"2006-01-02"
511940time.RFC1123

綜上資料所述,終於在 Go 過去了 13 年後,將會在 Go1.20 增加如下三個常量:

DateTime   = "2006-01-02 15:04:05"
DateOnly   = "2006-01-02"
TimeOnly   = "15:04:05"

新版本中直接引用即可。

以後問這是什麼意思的同學,可能會變少。

支援比較:Time.Compare

目前在標準庫中,有 3 個方法來比較 time.Time 物件,分別是:Before()、Equal() 和 After(),作用上類似 <、== 和 >。但缺少 <= 和 >= 的等價物,因此在程式中實施起來會比較麻煩。

經常一番討論,將會在 Go1.20 支援 Time.Compare,以此來達到類似的效果。作用是將 Time 物件 t 和 u 兩者進行比較。

函式返回如下幾種結果:

  • 如果 t 在 u 之前,則返回 -1。
  • 如果 t 在 u 之後,則返回 +1。
  • 如果它們相同,則返回 0。

原始碼如下:

func (t Time) Compare(u Time) int {
    var tc, uc int64
    if t.wall&u.wall&hasMonotonic != 0 {
        tc, uc = t.ext, u.ext
    } else {
        tc, uc = t.sec(), u.sec()
        if tc == uc {
            tc, uc = int64(t.nsec()), int64(u.nsec())
        }
    }
    switch {
    case tc < uc:
        return -1
    case tc > uc:
        return +1
    }
    return 0
}

函式內部比較簡單。

總結

Go Time 一直都是話題榜上的老面孔。這一次在 Go1.20 的新特性中,對 2006-01-02 15:04:05 常用的時間點進行了常量宣告,便於我們後續直接引用,不用 “死記硬背”。

在 Time 物件的比較上,也補全了 Compare 方法,便於兩個時間物件之前之後的對比。

Go1.20 將在明年 2023 年 2,3 月份左右就可以見到了。11 月底會發預覽版本。衝不?

文章持續更新,可以微信搜【腦子進煎魚了】閱讀,本文 GitHub github.com/eddycjy/blog 已收錄,學習 Go 語言可以看 Go 學習地圖和路線,歡迎 Star 催更。

推薦閱讀

Go 圖書系列

推薦閱讀