您可能在電腦或其他設備上看到過 1970 年 1 月 1 日的日期,即使您當時並未出生。您可能會認為這代表了計算機中的一個重要日期,或者它是機器無法讀取時間時的一個隨機佔位日期。事實上,儘管該日期本身並不特別,但它代表了計算機如何計時的一個重要部分。與計算機中的所有內容一樣,導致這個日期的方法是有限的,意味著我們未來會遇到問題。這與計算機(和人類)如何追蹤時間的更有趣討論息息相關,這比您想象的要複雜得多。
1970 年 1 月 1 日的 00:00(午夜)UTC 是 Unix 時間的起點。起點指的是一個特定的、影響深遠的時刻,通常對應於一個計時系統的開始。Unix 是我們所稱的現代作業系統之一,始於 1960 年代末期。它是許多被稱為「類 Unix」的作業系統的基礎,包括 Linux、macOS 和 Android。Windows 則是主要的例外。在 Unix 開發過程中,其開發者需要一種方法來追蹤時間。
早期的一些嘗試使用 60Hz 的系統時鐘速度,但將其存儲在 32 位整數中會導致不到 2.5 年的時間就會用盡空間。經過一段時間,他們將計時方法改為使用秒,並選擇 1970 年 1 月 1 日作為一個「圓滿」的任意日期開始,認為 32 位整數的時間不會很快耗盡空間(稍後會詳細介紹)。至今,Unix 時間是通過追蹤自 1970 年 1 月 1 日午夜 UTC 以來經過的秒數來保持的。
Unix 時間的計算方式影響未來的技術挑戰
UTC(協調世界時間)是顯而易見的選擇,因為它已經是跨時區追蹤時間的標準。對於計算機來說,將兩個數字進行比較並計算它們之間的差異是相對簡單的,而不必擔心我們在時間方面的所有規則。該系統將時間戳,包括您所在時區與 UTC 的偏移,轉換為我們人類可讀的格式。您可能會在電子表格、應用程式、文件元數據、錯誤螢幕和其他各種地方看到 1970-01-01 的日期。除非這個日期恰好與某人的生日或其他重大事件相符,否則它通常是錯誤的結果。
如果一個類 Unix 系統嘗試檢查時間時遇到問題或接收到 0 值,它將默認為起點。如果您生活在落後於 UTC 的時區,您可能會將這些默認值顯示為 1969 年 12 月 31 日的晚些時候。
傳統的 Unix 時間是作為有符號的 32 位整數保留的,這是一個包含 32 位數字的二進制值,每一位都可以是 1 或 0。有符號整數可以追蹤正數和負數,而無符號整數只能是正數。在追蹤時間的情況下,使用有符號值是必要的,以便追蹤 1970 年之前的日期。由於有符號整數的第一位(最左邊)用於指示其是否為負數,這將可用的值範圍減半,與無符號數字相比。有符號整數的最大值可以表示為 2^31,或 4,294,967,295。
有符號值的範圍最高可達 2,147,483,647,最低可達 -2,147,483,648。因此,Unix 時間有一個「到期日」。一旦達到上限,最左側的數字將變為 1,這將導致其餘數字被解釋為負數。這將發生在 2038 年 1 月 19 日的 3:14:07 AM UTC,因此您會聽到這被稱為「2038 年問題」。一旦整數溢出,時間將錯誤地顯示為 1901 年 12 月 13 日的 8:45:52 PM UTC,並從那裡繼續計數。
值得慶幸的是,在此日期之前,我們還有充足的時間來實施應對措施。
大多數現代類 Unix 系統現在使用 64 位整數來追蹤時間,這可以在溢出之前追蹤大約 2920 億年——如果到那時還有人存在,將時間轉移到 128 位整數將是他們的問題。您的現代 MacBook 是 64 位的,運行良好,而像 iPhone 4 這樣的 32 位設備將會遇到麻煩。2038 年來臨時的主要風險在於無法輕易更新的舊系統,如嵌入在家電、車輛、相機等中的系統。
其中一些即使無法保持準確時間也不會受到重大影響,但如果時間是關鍵因素,未來 12 年內仍需更換任何這些設備。
Y2K 問題與 Unix 時間的不同之處
您可能會想知道這個時間問題是否與 Y2K(即「2000 年問題」)有關,這在新千年來臨時是一個重大擔憂。雖然兩者都與計算機如何保持時間有關,但過去的問題是由於十進制簡寫,而不是二進制溢出。計算機早期的日子,內存極為昂貴,因此程序員在各處節省資源。使用兩位數表示年份是常見的,假設前兩位數總是「19」。Y2K 的擔憂在於,當年份進入 2000 年時,計算機會將「00」解釋為 1900 年(或其他早期日期),造成依賴準確時間的程序出現各種問題。
當時這是一個重大恐慌,但最終並沒有如預期的那般糟糕(根據您的詢問,這要麼歸因於預防措施,要麼因為問題本身並不大)。
Unix 時間並不是計算機處理時鐘的唯一方式。許多機器擁有實時時鐘,類似於掛鐘,並在計算機關閉時使用 CMOS 電池保持供電。當該電池耗盡時,您的計算機時鐘將不會正確。Windows,作為前面提到的例外,從 1601 年 1 月 1 日午夜 UTC 開始,以 100 納秒的刻度追蹤時間。雖然這比 1970 年要早得多,但這個起點並不是隨機的;我們所使用的公曆每 400 年經歷一次完整的循環,因此 1601 年是 Windows 開發時最近一個循環的開始。
這是一個無符號的 64 位整數值(因為不太可能需要表示 1601 之前的日期),將在 30,828 年 9 月 14 日失效。
最後,還有 NTP(網絡時間協議),它通過互聯網將計算機的時間同步到極其準確的計時伺服器。如果計算機的計時方法出現故障或漂移,則會通過 NTP 接收修正。有很多其他與時間追蹤相關的方法,如即將被淘汰的閏秒、夏令時間、時區變更以及日曆轉變,但現在您對計算機如何追蹤時間有了更深入的瞭解。
項目 規格 處理器/SoC 64 位整數 最大值 2^31 (4,294,967,295)

