日期、時間與UTC

傳統日期的侷限

人類在對時間的測定上存在一個進化的過程,最早通過觀察天體的自轉與公轉來確定時間,比如地球自轉一週爲一天,月球公轉一週爲一月,地球公轉一週爲一年。

我們先考慮天和年,他們之間就像數學一樣存在一個粗糙的進制方案——365.25天爲1年。這種進制就像十進制數一樣可以有效壓縮日期的長度,比如我們可以記某某王朝存在了 300年,而不是 109575 天。

而說他粗糙是因爲進制不是整數,這在使用上多有不便,沒人喜歡在大白天突然過年吧。因此制定曆法(公曆)的人做出妥協:允許計時出現不超過 1 天的偏差,以實現整數進制,即 365天進一年。當累計偏差達到一天時在 2 月最後一天之後再加一個閏日。我們通常管這樣的年叫做閏年。

此時,是一個確定的時間單位,而不是了,因爲一年可能有 365 天也可能有 366 天。

作爲公立的格里曆在閏日的規則上更精確一些,可參考 wiki: 格里曆

以格林尼治午夜爲 0 點,以觀察太陽爲手段計時的標準叫做 世界時(UT)。此時的秒定義爲一天的 1 / 86400。

另一套計時標準

後來人們發現靠天文觀測來計時不是那麼準,尤其地球自轉和公轉的速度居然不是恆定的。於是在 1967 年人們重新定義了,把它從世界時一天的 1/86400 改爲了

銫133原子基態的兩個超精細能級間躍遷對應輻射的9,192,631,770個週期的持續時間

銫原子鐘 對秒的重新定義帶來了一種新的計時標準——國際原子時(TAI),同時也帶來了像 之間“粗糙進制”的問題:現在世界時的一天也不是標準的 86400 秒了。國際原子時從 1958年初開始計時,到 2016 年 11月已經比世界時快了 37s。(地球轉的慢了)

UTC

現在電信業遇到了一個麻煩,本身他們需要使用原子鐘計時,但又不得不服從世界時,畢竟只要人類還生活在地球上,時間就都要向太陽對齊。人們決定再定義一個時間,叫做 UTC,比世界時的 UT 多了一個 Coordinated,其協調的就是原子時和世界時之間的差距。

協調的方案就像閏日一樣,人們選擇了閏秒。人們把 UTC 1972-01-01 00:00:00 向國際原子時的 00:00:10 做了一次對齊(原子時是不閏秒的),然後以原子秒爲基礎計時,同時監測與世界時的差距,適時閏 1s 或 -1s。一般閏秒的時刻選擇在6月的最後一秒或12月的最後一秒。

因爲原子秒的長度定義本身就參考了上百年觀測的平均太陽日時間,所以這個誤差其實相當低,從1972年到現在總共才閏了 27 次,且全部是 +1s。即最近地球轉的比過去慢。(注意閏秒其實是隨機而不可預測的,最近幾十年轉的慢,也許過幾年就轉得快了,到時候就要 -1s

對於 UTC 的時間是哪個時區的問題,因爲它總是向世界時對齊,而世界時是格林尼治時間,所以 UTC 也就是向格林尼治時間對齊。

UNIX 時間

UNIX 時間是以 UTC 時間 1970-01-01T00:00:00 爲原點到現在的秒數偏移量。但因爲編程的問題,它不考慮閏秒。所以它只是在跳秒的時刻上與原子時同步,而累計的秒數其實是世界時的秒數。

對於程序來說,因爲閏秒的不規律性,如果要計算當前到 1970-01-01T00:00:00 的原子秒數,就需要額外存儲每一次閏秒的記錄。又因爲人們日常需求中其實並不關心閏秒,使用原子秒記錄反而會產生很多麻煩,所以就這麼用了。

閏秒帶來的時刻問題,比如有的系統會產生 23:59:60 這樣的時刻,或者有的系統會走兩次 23:59:59,就需要用戶自己去處理了。而一般情形的編程下,可以認爲 UNIX 時間與 UTC 時間是等價的。UTC 閏秒在計算機裏也通常會被捨棄,不然的話每次計算時間還要依賴 ntp 服務器這是不現實的。即在 Python 裏:

>>> (datetime.utcnow() - datetime.utcfromtimestamp(0)).total_seconds() == time.time()
>>> True

而在現實中上式不等。到現在爲止,應該有 27s 的差距。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章