Go 憑什麼搞特殊?不用 yyyy-mm-dd,非得要 2006-01-02 15:04:05。。。
大家好,我是煎魚。
前段時間我寫了一篇《Go1.20 中兩個關於 Time 的更新,終於不用背 2006-01-02 15:04:05 了!》,文中有提到 Go 的參考時間格式是:2006-01-02 15:04:05,並解釋這麼設計的緣由。
有很多同學表示不解。如下圖:
甚至我在點外賣時還特意看了,某團在個人資訊頁中的生日那一欄,是如此顯示的:
那熟悉的 yyyy-mm-dd。我甚至一度懷疑這是不是 BUG,這可能只有程式設計師懂?
ISO 8601 規範
尤其是有提到 ISO 8601,這是一個國際標準化組織提供的一個有關時間表示的規範,其中我們最為熟悉的是日期表示法。
具體介紹摘抄自網路,如下:
YYYY-MM-DDThh:mm:ss[.mmm]TZD
2022-11-18T10:05:45+08:00
- YYYY:四位數年份,不全補齊。
- MM:月份、兩位,不全補齊。
- DD:兩位數的天(day of the month),01~31。
- T:指示時間元素的開始字元。
- hh:兩位數的小時,00~23。
- mm:兩位數的分鐘,00~59。
- ss:兩位數的秒,00~59。
- mmm:三位數的毫秒,000~999。
- TZD:時區指示符:Z 或 +hh:mm 或 -hh:mm,+ 或 - 表示時區距離 UTC 時區多久。
為什麼這麼特別
我們之前的文章都在介紹 2006-01-02 15:04:05 這個時間點代表的含義是什麼,代表什麼意思:
Jan 2 15:04:05 2006 MST
1 2 3 4 5 6 -7
這有一個大大的問題,那就是 Go 為什麼不遵守 ISO 8601 規範,非得用這個?這莫非是一種新的創新...
在我猛翻後,找到了在對標準化辯解的背後。實際上 @Rob Pike 在 2014 年在《What is the reason behind time.Parse using a reference time?》進行了解釋,說明為什麼會選擇這個時間點。
“這個選擇是由我的 Unix 機器上的 date 命令的輸出所決定的。我應該意識到格式會隨著地區的不同而變化。錯了。但我仍然可以說它很容易記住,並且有據可查。”
這就是原因。
為什麼那麼難受
大家一開始可能以為只有我們用的比較變扭?但其實不止,各地的人都擁到了社群裡反饋過這個問題。
歸根到底還是世界各地用的時間格式不一樣,而 Go 這裡根據 Rob 的反饋,實際上它只是以某國為時間中心的 “隨機” 格式,對應的就是 “1 2 3 4 5 6 7”。
例如:“Jan 2 3:04 pm 06 -0700”。
所代表的意義:
- Jan:第一個月
- 2:第二天
- 3:下午 3 點
- 4:第 4 分鐘
- 5:第 5 秒
- 6:本世紀第 6 年
- 7:比格林威治標準時間晚 7 小時。
看起來很有規律,但...
總結
Go 的這一項時間規範選擇,是比較特殊的。很多同學希望他 “改邪歸正”,用回 YYYY-MM-DD,別再用 2006-01-02 15:04:05 了。
這顯然不現實,首先是 Go1 相容性不允許,其次一山不能容二虎,加估計都沒法加。這件事已成定局。
建議還是記好 Go1.20 要新增的 3 個常量,這個以後不用去背和查了。如下:
go
DateTime = "2006-01-02 15:04:05"
DateOnly = "2006-01-02"
TimeOnly = "15:04:05"
這個比較現實。
這個設計,我認為是技術債務了。將會持續陪伴 Go1 終身,你我皆為局中人。
Go2 有戲嗎?暫未看到。
推薦閱讀
- 前有 45 億資料被扒,現有 Go 工具鏈想要我的使用資料。。。
- 醒醒吧,未來不會有 Go2 了!
- Go1.20 將會修改全域性變數的初始化順序。梅開二度,繼續打破 Go1 相容性承諾!
- 多個著名 Go 開源專案被放棄,做大開源不能用愛發電,更不能只靠自己!
- Go 憑什麼搞特殊?不用 yyyy-mm-dd,非得要 2006-01-02 15:04:05。。。
- PGO 是啥,咋就讓 Go 更快更猛了?
- Go 十年了,終於想起要統一 log 庫了!
- Go 大佬良心發現,願意給 map 加清除了?
- Go 為什麼能火?歸功於這 5 個方面
- if err != nil 太煩?Go 創始人教你如何對錯誤進行程式設計!
- 這個新 Go 錯誤處理提案,能解決問題不?
- Go1.18 新特性:引入新的 netip 網路庫
- Go1.19 那些事:國產晶片、記憶體模型等新特性,你知道多少?
- Go 為什麼不支援字首自增運算子?
- Go 內聯優化能讓程式快多少?
- Go 錯誤處理新思路?用左側函式和表示式
- 騷爆了... Go 錯誤處理中再套個娃,能解決煩惱不?
- 被折磨了 13 年,Go 怎麼解決再賦值的坑?
- Go 泛型變更:約束太醜了,先移動到 x/exp 做實驗性功能
- Go1.18 新特性:多 Module 工作區模式