2038 年可能是程序員一場(chǎng)危機(jī)!
大家好,我是小林。
2038 年可能是程序員面臨的一道坎,因?yàn)檫@關(guān)乎時(shí)間戳的問題。
今天就跟大佬嘮嗑下這個(gè)事情。
文章選自維基百科:2000年問題和2038年問題,感興趣讀者可以自行閱讀英文版,信息量更大一些。
2000 年問題
千年蟲問題,是指由于計(jì)算機(jī)程序設(shè)計(jì)的一些問題,使得計(jì)算機(jī)在處理2000年1月1日以后的日期和時(shí)間時(shí),可能會(huì)出現(xiàn)不正確的操作,從而可能導(dǎo)致在2000年1月1日零點(diǎn)工作停頓甚至是發(fā)生災(zāi)難性的結(jié)果。
一般來說,由于計(jì)算機(jī)程序中使用兩個(gè)數(shù)字來表示年份,如1998年被表示為98、1999年被表示為99,而2000年被表示為00。
這樣將會(huì)導(dǎo)致某些程序在計(jì)算時(shí)得到不正確的結(jié)果,如把“00”誤解為1900年。在嵌入式系統(tǒng)中可能存在同樣的問題,這有可能導(dǎo)致設(shè)備停止運(yùn)轉(zhuǎn)或者發(fā)生更加災(zāi)難性的后果。
畫外音:這個(gè)對(duì)于我們程序員來說很好理解,有時(shí)候不知道業(yè)務(wù)發(fā)展會(huì)怎么樣,基于資源和當(dāng)時(shí)的發(fā)展情況來考慮,設(shè)置空間余量不足,也是常有的事情。
2038年問題
UNIX操作系統(tǒng)是美國AT&T公司貝爾實(shí)驗(yàn)室于1969年完成的操作系統(tǒng),最早Ken Thompson、Dennis Ritchie、Douglas McIlroy于1969年在AT&T貝爾實(shí)驗(yàn)室開發(fā)。
于1971年首次發(fā)布,最初是完全用匯編語言編寫。后來在1973年用一個(gè)重要的開拓性的方法,Unix被丹尼斯·里奇用編程語言C重新編寫,高級(jí)語言編寫的操作系統(tǒng)具有更佳的兼容性,能更容易地移植到不同的計(jì)算機(jī)平臺(tái)。
#ifndef __TIME_T
#define __TIME_T
typedef long time_t;
#endif
在32位系統(tǒng)中time_t實(shí)際是一個(gè)4字節(jié)的有符號(hào)長整型,其值表示為從UTC(coordinated universal time)時(shí)間1970年1月1日00時(shí)00分00秒到當(dāng)前時(shí)刻的秒數(shù)。
由于time_t類型長度的限制,它所表示的時(shí)間不能晚于2038年1月19日03時(shí)14分07秒(UTC),那么當(dāng)時(shí)間戳到達(dá)最大值2147483647會(huì)發(fā)生什么呢?
畫外音:要理解2038年問題就必須要理解time_t和signed 32bit的計(jì)數(shù)。
2038-01-19 03:14:08



畫外音:這好像還是個(gè)大事情,一下子回到了1901年……
32位操作系統(tǒng)
在計(jì)算機(jī)應(yīng)用上,2038年問題可能會(huì)導(dǎo)致某些軟件在2038年1月19日3時(shí)14分07秒之后無法正常工作。
所有使用POSIX時(shí)間表示時(shí)間的程序都將受其影響,因?yàn)樗鼈円宰?970年1月1日經(jīng)過的秒數(shù)(忽略閏秒)來表示時(shí)間。
在大部分的32位操作系統(tǒng)上,time_t使用一個(gè)有正負(fù)號(hào)的32位有符號(hào)整數(shù)存儲(chǔ)計(jì)算的秒數(shù)。依照time_t標(biāo)準(zhǔn),在此格式能被表示的最后時(shí)間是2038年1月19日03:14:07,星期二(UTC)。
一旦超過這個(gè)時(shí)刻,時(shí)間將會(huì)繞回且在內(nèi)部被表示為一個(gè)負(fù)數(shù),并造成程序無法工作,因?yàn)樗鼈儫o法將此時(shí)間識(shí)別為2038年,而可能會(huì)依個(gè)別實(shí)現(xiàn)而跳回1970年或1901年。因此可能產(chǎn)生錯(cuò)誤的計(jì)算及動(dòng)作。
我們來看下官方的警告:

畫外音:官方警告最為真實(shí)…
64位操作系統(tǒng)
大部分64位操作系統(tǒng)已經(jīng)把time_t這個(gè)系統(tǒng)變量改為64位,但是仍然有數(shù)以億計(jì)的32位系統(tǒng)在運(yùn)行中,特別是許多嵌入式系統(tǒng)。
32位time_t的使用亦被編碼于文件格式,例如眾所周知的ZIP文件壓縮格式。其能存在的時(shí)間遠(yuǎn)比受影響的機(jī)器長。
新的64位運(yùn)算器可以記錄至約2900億年后的292,277,026,596年12月4日15:30:08,星期日(UTC),基本上可以徹底解決時(shí)間回環(huán)問題。
畫外音:換了64位 舒服了…
2038年問題的影響
2038年問題與之前的千年蟲問題的殺傷力是不一樣的,千年蟲屬于應(yīng)用程序的問題,而2038年問題卻是系統(tǒng)級(jí)的,有更大的殺傷力。
Linux Kernel 5.6 的開發(fā)者已經(jīng)準(zhǔn)備好著手解決將在下一個(gè)十年到來的 2038 年問題。Linux 5.6 也成為第一個(gè)為 32 位系統(tǒng)準(zhǔn)備運(yùn)行到 2038 年之后的主線內(nèi)核。

至于像MySQL等組件同樣面臨2038年問題,目前還有17年的時(shí)候,我們相信可以應(yīng)對(duì)這次危機(jī)。
畫外音:還有17年呢,說不定那會(huì)兒我都退休了,改造的事情交給年輕人吧…
