2038年問題

軟體在2038年無法工作的問題

2038年問題是指在使用POSIX時間的32位計算機應用程序上,格林尼治時間2038年1月19日凌晨03:14:07(北京時間:2038年1月19日中午11:14:07)之後無法正常工作。

網路時代,機會與危機共存,這也許是你我必須面對和必須付出的代價。“千年蟲”解決之後,會不會有新的“蟲”出現?回答是肯定的,“2038年”就是一個新的關卡。

32位時間表示


前言

2038年問題演示
2038年問題演示
在計算機應用上,2038年問題可能會導致某些軟體在2038年無法正常工作。所有使用POSIX時間表示時間的程序都將受其影響,因為它們的時間起點是格林尼治時間1970年1月1日0時0分0秒(這個時間名叫 the Unix Epoch),它們用the Unix Epoch經過的秒數(忽略閏秒)來表示時間。這種時間表示法在類Unix(Unix-like)操作系統上是一個標準,並會影響以其C編程語言開發給其他大部份操作系統使用的軟體。在大部分的32位操作系統上,此“time_t”數據模式使用一個有符號32位整數(signed int32)存儲計算的秒數。依照此“time_t”標準,在此格式能被表示的最後時間是第2147483647秒(代表格林尼治時間2038年1月19日凌晨03:14:07)。下一秒,即格林尼治時間2038年1月19日凌晨03:14:08,由於32位整型溢出,時間將會被“繞回”(wrap around)成一個負數,變成了第 -2147483648 秒(代表格林尼治時間1901年12月13日20:45:52),造成應用程序發生嚴重的時間錯誤,而無法運行。

正文

也許大家都已經知道計算機的2000年問題是什麼概念,但是什麼時候又冒出來一個2038年問題的呢?
C語言編製的程序不會碰到2000年問題,但是會有2038年問題。這是因為,大多數C語言程序都使用到一個叫做“標準時間庫”的程序庫,這個時間庫用一個標準的4位元組也就是32位的形式來儲存時間信息。
當初設計的時候,這個4位元組的時間格式把1970年1月1日凌晨0時0分0秒(這個時間名叫 the Unix Epoch)作為時間起點,這時的時間值為0。以後所有的時間都是從這個時間開始一秒一秒累積得來的。
比方說如果時間已經累積到了919642718這個數值,就是說這時距離 the Unix Epoch已經過去了919642718秒,換算一下就應該是1999年2月21日16時18分38秒。
這樣計算時間的好處在於,把任意兩個時間值相減之後,就可以很迅速地得到這兩個時間之間相差的秒數,然後你可以利用別的程序把它換算成明白易懂的年月日時分秒的形式。
要是你曾經讀過一點兒關於計算機方面的書,你就會知道一個4位元組也就是32位的存儲空間的最大值是2147483647,請注意!2038年問題的關鍵也就在這裡———當時間一秒一秒地跳完2147483647那驚心動魄的最後一秒后,你猜怎麼樣?
答案是,它就會轉為負數也就是說時間無效。那一刻的準確的時間為2038年1月19日星期二凌晨03:14:07,之後所有用到這種“標準時間庫”的C語言程序都會碰到時間計算上的麻煩。
這就是2038年問題。
但是大家也不用太過緊張。2038年問題比千年蟲(the Millennium bug)問題解決起來相對要容易一些,只要給那些程序換一個新版本的“標準時間庫”就可以了,比如說,改用8位元組64位的形式來存儲時間。這樣做並不怎麼費事,因為在C程序中“標準時間庫”是相對獨立的一個部分,裡面的時間表達都有自己的一套時間類型和參數(而在碰到Y2K的那些大型主機中,時間格式大都沒有一)。
說到這裡,一些冰雪聰明的菜鳥DDMM們應該可以聯想到,WindowsNT用的是64位操作平台,它的開始時間是1601年1月1日———但是它每過1個納秒就跳一下,因此,WindowsNT它會碰到的是2184年問題……
而在一些用64位來表示時間的平台上,例如DigitalAlpha、SGI、Sparc等等,想要看到它們的時間出錯你得等到天荒地老———那大概是2920億年。到那時,位於獵戶座旋臂太陽,已經是黑矮星或暗黑物質,獵戶座旋臂已經被重力波震斷,銀河系大概則已經變成小型似星體了。
所以,給那些準備攢機的菜鳥DD一個建議,除非您想要把資料流傳給下一個宇宙,一台64位的電腦已經足夠。
總之,32位的最後時間是2038年1月19日03:14:07,星期二。
64位的最後時間約2900億年後的292,277,026,596年12月4日15:30:08,星期日。

64位時間表示


新的64位運算器可以記錄至約2900億年後的292,277,026,596年12月4日15:30:08,星期日(UTC)。

解決進展


目前並沒有針對現有的CPU/操作系統搭配的簡單解決方案。直接將POSIX時間更改為64位模式將會破壞對於軟體、數據存儲以及所有與二進位表示時間相關的部份的二進位兼容性。更改成無符號的32位運算器(integer)則會影響許多與時間改變相關的程序。
大部份64位操作系統已經把time_t改為64位整型。不過,其他現有架構的改動仍在進行中,不過預期“應該可以在2038年前完成”。然而,直到2006年,仍然有數以億計的32位操作系統在運行中,特別是許多嵌入式系統。相對於一般電腦科技18至24個月的革命性更新,嵌入式系統可能直至使用壽命終結都不會改變。32位time_t的使用亦被編碼於文件格式,例如眾所周知的ZIP壓縮格式。其能存在的時間遠比受影響的機器長。