前幾天,當我在寫通信科普文章的時候,突然有一種時空錯亂的感覺,恍惚間感覺這個場景十分熟悉,好像在不久之前,同樣的電腦,同樣的微風拂面,同樣的我,做著同樣的事情。在另外的一個時空中還有一個你,他經歷過相同的事情,於是這種熟悉感就會傳遞給你。
但是彰顯這個世界,是一個虛假世界的Bug,卻不斷的在我們身邊出現:
為什麼會有這麼多的證據,表明我們穿越到了1970年1月1日,這個日子有什麼特殊的嗎?
然後我們來看一下這個日期:1970.1.1,好像沒有什麼特別的啊?如果說宇宙大爆炸代表了宇宙的誕生起點,那麼1970.1.1就代表著計算機的誕生時間點。
是不是感覺很奇特,現在我們隨處可見的計算機、智慧型手機,竟然才誕生50年!從來沒有一個事物可以發展的如此迅速,並如此劇烈得改變人類的生活。1969年8月,貝爾實驗室程式設計師肯.湯普遜耗時一個月,開發出了Unix的第一個版本。他估計也想不到,這個B語言開發的全新作業系統,會產生如此深遠的影響。儘管Unix一出世就得到了大家的肯定,但是肯.湯普遜並沒有滿足,他又和同事丹尼斯裡奇一起改進了B語言,開發出C語言,並重寫了Unix,新版本於1971年發布。同年,《Unix Programmer's Manual》出版,將格林威治時間(GMT)1971年1月1日0時0分0秒作為作業系統的起始時間。現今的計算機系統,或多或少受Unix的影響,延續Unix的計時方式。格林威治時間(GMT)1970年1月1日0時0分0秒從此成為Unix世界的起始時間,甚至超越Unix成為整個計算機世界的起始時間。Unix中常常使用一個數字記錄時間,即Unix紀元時間(格林威治時間1970年1月1日00:00:00)到當前時間的秒數。(根據系統的精度,時間單位有時為毫秒,有時為納秒)。大於0表示在起始時間之後,小於0表示在起始時間之前。這個數字有時是浮點類型、有時是整數類型,統一稱為時間戳(Timestamp)。一開始的Unix都是32位的,所以時間戳的取值範圍為-2147483648(231) ~ 2147483647(231-1),不過一般我們認為計算機不會在1970年前使用,所以使用的是時間戳的正整數,即最大值為2147483647(231-1)。最初Unix的規定是:時間戳每變化一次,就表示時間經過了1/60秒。比如時間戳取值為3600,表示以格林威治時間1970年1月1日00:00:00為起點,經過了3600x1/60秒= 60秒,那現在的時間就是1970年01月01日00時01分00秒。人們很快就發現了問題:一個時間戳代表1/60秒的話,2147483647x(1/60秒)/(24小時x60分鐘x60秒)=414.3天,也就是說只需要400多天,時間戳就全用完了。
設計出一個只能使用400多天的作業系統,顯然不是大家的願望。於是Unix修改了規定:時間戳每變化一次,就表示時間經過了1秒。這個規定延續到現在,還在使用。比如時間戳取值為3600,表示以格林威治時間1970年1月1日00:00:00為起點,經過了3600秒,那現在的時間就是1970年01月01日01時00分00秒。從1/60秒擴大到1秒,作業系統的時間也從400多天擴展到了68年,雖然時間上仍然不多,但對於當時的人們來說,已經是足夠使用的了。看著這裡,你是不是不禁要問,1970+68豈不是2038年,這不也快到了嗎?難道到時候再修改規定?
沒錯,32位時間戳能代表的最長時間是68年,到2038年01月19日03時14分07秒,便會到達最大時間。過了這個時間點,所有32位作業系統時間便會變為 10000000 00000000 00000000 00000000,也就是1901年12月13日20時45分52秒,會出現時間回歸的現象,很多軟體便會運行異常了。當初Unix使用的是32位,導致時間戳的取值有限。而現在大部分的計算機,都是64位的了。時間戳的取值範圍擴大為-9223372036854775808(263) ~ 9223372036854775807(263-1)。換算成時間的話,64位的時間戳,可以覆蓋了1970年前2000多億年,後2000多億年,絕對夠用到宇宙的盡頭了。
原來如此,那到底為什麼有些應用程式中會顯示1970.1.1呢?我們日常使用的各種應用程式,都是構建在作業系統上的。當需要展示時間時,應用程式都要從作業系統中獲取時間戳的取值。所以,1970.1.1的出現,最大的可能就是應用程式在獲取時間戳的時候,出現了Bug。
應用程式使用了不恰當的數值、或者無法獲取系統時間戳的時候,就只能使用時間戳的默認取值。而在計算機中,時間戳的默認值通常是0。時間戳為0,表示時間為(GMT)1970年1月1日0時0分0秒。中國使用北京時間,處於東8區,相應就是早上8點。因此在中國,時間戳出錯了,就經常會顯示為1970年1月1日08:00。再遇到1970.1.1的時候,就可以會心一笑:這個應用程式肯定出現Bug,沒法獲取到正確的時間戳了。應用程式獲取時間戳時出現錯誤,最多就是顯示了錯誤的時間。未來的時光機,還構造在計算機作業系統上的話,想要穿越時空,就必須以紀元時間為坐標,設置要穿越的時間點,即設置正確的時間戳。
時光機的設計者或者說是程式設計師們,一定要打好時間戳哦:用了32位的時間戳,就只能回到1902年11月25日~2038年01月19之間;用了64位的時間戳,那就隨意了,1970年的前後共4000億年的時空,足夠你任意翱翔了!注意:穿越到1970年1月1日之前時,一定要把時間戳設置為負數。
那麼,各位小夥伴們,你們有沒有遇到過Bug呢?
不管是應用程式的Bug,還是現實世界的Bug,歡迎分享哦~
我們是一群平均從業年限5+的通信專業工程師。
關注我們,帶你了解通信世界的精彩!
你點的每個在看,我都認真當成了喜歡