ISO-8601 是國際標準化組織提供的一個有關時間表示的規範。
如下:
1970-01-01T00:00:00Z
可能是我們最常看到的格式了,這個表示的是一個 Epoch 時間,其實也不完全一定是,因爲在上面沒有表示出毫秒。
關於上面的時間格式解讀如下:
- T 爲日期和時間的分隔符,無特殊意義,猜測可能使用了英文單詞 time 的首字母 T 吧。
- Z 表示的是時區。應該取的是 Zone 的首字母,如果你看見表示的格式有 Z 的話,那麼就說明當前的時間是 UTC 時間。
格式擴展
完整的 ISO 8601 可以用下面的格式來表示 2021-08-13T14:20:18.992847200-04:00
在上面的格式中的 字母 T
請參考前面的解釋。
- 無字母 Z,如果沒有字母 Z的話,應該使用的是 + 或者 - 符號,+ 表示的是東,比如說北京, - 表示的是 西部,比如 -04:00 表示的是西 5 區的美國東部時間。
- 在秒後面使用 點號
.
例如 上面的.992847200
來表示納秒,這個時間是可以省略的。
其實上面的時間格式都是可以進行格式化,取部分數據,或者省略掉數據,如果省略的數據在初始化的時候就被填充 0 。
Epoch 時間
紀元(Epoch)是指具有歷史意義的某一刻,其實就是一個參考點。
Unix 紀元是 Unix 或類 Unix 系統,一些C/C++,Java等編程語言使用的紀元,從1970年一月一日00:00 開始。而其他的操作系統或者編程語言,使用的就是不一樣的紀元起始日期了,比如 Microsoft C/C++ 7.0 使用的是 1899年12月31日。
從 Unix 紀元(1970-01-01-00:00:00)就是Unix時間的零點,以後的時間是正的,而 Unix 紀元之前的時間就是負值。
爲什麼 Unix 系統中紀元的時間是 1970 年
這個問題得去問 Unix 之父:Ken Thompson 和 Dennis Ritchie了,是他們選擇這個時間作爲 Unix 系統的紀元時間的。
第一版的 Unix 程序員手冊是 1971年11月份出版的,上面定義Unix時間是:從1971年1月1日00:00:00開始,單位是一秒的六十分之一。
這意味在Unix時間的最早版本中,時間計數器以 60Hz 的頻率(芯片的振盪器頻率)遞增,每隔 1/60 秒,計數器就加一。當時使用的整數計數器是 32 位的,這樣 Unix 時間能夠表示的範圍就非常受限了,2^32/60/3600/24/30/12 大約是 2.3年。
所以後來經過多次更改,頻率變成了1Hz,紀元時間改爲了 1970年1月1日00:00:00。
有一種說法是Unix 操作系統誕生於 1970 年,但實際上並不是的,在 1969 年左右,Unix的概念就已經誕生了,Unix 的最早版本已經誕生了。Wired 網站上的一篇文章寫道:Ritchie 說這個時間其實是隨意選擇的,因爲需要一個統一的日期來作爲時間的起點,而1970年的元旦,看起來是最方便的。
2038 年問題
2038 年問題又叫 Unix 千年臭蟲或 Y2K38 錯誤。在時間值以帶符號的 32 位整數來存儲或計算的數據存儲情況下,這個錯誤就有可能引發問題。
可以用 Unix 帶符號的 32 位整數時間格式來表示的最新時間是 2038年1月19日03:14:07UTC,這是1970年1月1日之後過了2147483647秒。過了那個時間後,由於整數溢出,時間值將作爲負數來存儲,系統會將日期讀爲1901年12月13日,而不是2038年1月19日。
用簡單的語言來說,Unix機器最終將會耗盡存儲空間來列舉秒數。所以,到那一天,使用標準時間庫的C 程序會開始出現日期問題。
其實就是因爲整數的最大計數在這一天會溢出,導致無法正確處理時間。
感覺人類文明就是和時間和存儲過不去。