代碼中的人文故事:從一個Java的「Bug」提及

緣起

這幾日閒來無事擼代碼,無心中發現一樁趣事。原覺得是一個Java的bug,沒想到通過一系列死磕,挖掘出了一段和中國歷史乃至人類文明相關聯的人文故事,不由唏噓感嘆一番。python

這件事的緣起很簡單,我在實現計算兩個日期天數距離邏輯的過程當中,發現了一個很詭異的事情,一樣的起始日期,用python和Java計算出的結果竟然不同!數組

例如,計算一個1990年1月1日到1990年9月4日之間的天數,用python計算如圖:函數

clipboard.png

得出天數爲246。能夠看到,python的API設計簡單。學習

用Java計算則不一樣了,衆所周知Java推薦的Calendar API不是通常的麻煩,實現函數以下:測試

clipboard.png

按照這個邏輯測試以下:spa

clipboard.png

clipboard.png

WTF!?得出的天數竟然是245天?爲何和Python算出來的不同?我立刻實際數了一下,應該是246天,Python算的結果是對的!.net

仔細覈對了程序實現,沒毛病啊?難道有精讀損失?設計

狐疑(懵逼)

進而加入以下輸出:3d

clipboard.png

clipboard.png

什麼鬼?這0.0416666667天跑哪裏去了?需知:對象

clipboard.png

也就是說,Java計算的時間和實際正好差了一個小時!

無獨有偶,各類百度後,竟然發現了和我有相似疑問的兄弟:
https://ask.csdn.net/question...
然而這個提問下並無靠譜的答案!

這樣看,彷佛很像時區上出了問題,然而並非,先後Calendar對象的時區徹底一致!都是Asia/Shanghai!

由此不免要想,難道Java代碼有Bug?把這一個小時給吃了?好吃嗎?啥味道?

然而,用一樣的函數,計算990年1月1日到1990年12月4日之間的天數,有一切正常了!

clipboard.png

心中萬馬奔騰啊!

clipboard.png

通過一番探索,我又寫了以下代碼:

clipboard.png

驚奇地發現:

clipboard.png

進而又發現:

clipboard.png

由此我靈機一動,又寫了一段代碼,找到從1900年至今全部當天長度非24小時的日期!

clipboard.png

此中必有蹊蹺!

豁然

然而這對於沒文化的我來講,實在是一件不可理喻的事情。只能從源碼入手了!

找源碼的過程就再也不贅述了,總之,時間的偏移來自於一個zoneOffsets的數組,而這個數組中除了由於時區而產生的偏移外,還有一個神祕的DST_OFFSET!

clipboard.png

找到這裏,這個謎團即將揭曉了!

啥是DST_OFFSET呢?

clipboard.png

沒錯,daylight saving offset,也就是夏令時!

也就是說,中國的1990年4月15日這天裏,人爲地將時間撥快了一個小時,1990年9月16日這天再撥慢回來。進一步說,中國的1990年4月15日這天確實是23個小時,1990年9月16日這天也確實是25小時,Java沒搞錯!

也就是說以前找到的全部非24小時的日期,都是中國政府(或國民政府)施行夏令時調整的日期,這段歷史斷斷續續地持續了半個多世紀!而Java的Calendar API將其忠實地記錄了下來。

clipboard.png

關於夏令時詳情見百度百科
哈哈哈,真相揭曉,好感慨好激動。因此說,這並非Java的bug,而正是Java嚴謹的體現!Calendar API確實設計的很爛很不友好,但並不表明其中有bug,相反地,這也正體現了其中的工程師精神。

這就引出了一段已經被淡忘的歷史,不少90年出生的朋友能夠問問父母,90年和91年是我國至今爲止實行夏令時的最後兩年,我國曾經也想向美國等西歐國家學習,充分利用太陽下的時光!年輕的小朋友問問大家的父母,必定能勾起他們的一段回憶!

這就是隱藏在Java代碼中的一段歷史,一段已經被遺忘的人文故事!

想了解這段歷史的同窗可戳:

還記得大明湖畔的夏令時嗎?

只要刨根問底,必定有意想不到的收穫!感受解決了個大謎團!

相關文章
相關標籤/搜索