一日在給一個時間轉換函數getUTCTimeFromLocal(StringsLocalTime) 做單元測試。作爲一個有很多年開發經驗的我,用例不能太小家子氣吧。於是給了個“1921-1-1 00:00:00”作爲輸入參數。結果發現,其他的用例執行都是OK,就這個 古老的日子NG了。
用到的函數也很基礎:
DateFormat dateTimeFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
for (String date : dateString) {
System.out.println(date + "=" + dateTimeFormat.parse(date));
}
難道是Java的SimpleDateFormat類不支持太遠的時間?我又換了其他一些輸入參數,發現1929年以後的時間都是對的啊。1928年就出問題了。
難道是夏令時?但是網上又查了下,雖然世界上有110個國家在實行夏令時,但我國在1986到1991年間實行了6年的夏令時。(由於省電效果不抵需要適應時間的弊端,1992年4月5日後不再實行)何況現在差的時間遠沒有1個小時。
仔細看了下,雖然輸出結果和預想的不太一樣。但似乎差的不是很多。日期和小時都是對的,差的只是分和秒。更精確的說是就差了5分52秒。對於這個結果,我很無語,做java這麼多年,還從來沒碰到這個事情。這個時間點很奇怪,是年末哦。這個又讓我想起了“閏秒”這個天文事件。由於地球自轉的不均勻性和長期變慢性(主要由潮汐摩擦引起的),會使民用時和原子時之間相差超過到±0.9秒時,爲了保持民用時和原子時的同步,由國際計量局統一規定在年底或年中對協調世界時增加或減少1秒的調整。就把世界時向前撥1秒(負閏秒,最後一分鐘爲59秒)或向後撥1秒(正閏秒,最後一分鐘爲61秒)。2012年我國曾宣佈我國7月1日進行閏秒調整,屆時將現7:59:60。自1971年首次增加閏秒以來,已經調整過了24個閏秒。但是現在差的不是1秒啊。所以閏秒的假設也被否定了。
然後,我又做了2個實驗。1,在.NET下執行了類似的函數。 二是在linux下執行了同樣的函數。結果都沒有出現類似情況。
Linux下的java 問題同樣出現。.NET下沒有問題。看來是Java類庫自身的實現問題了。但是現在已經是java7了。如果是bug的話,也該早就被發現了哦。
那這個是中國這個東八區纔有的現象嗎?我調到了東7和東9,發現是正常的。看來這個是跟東8區有關了。而且跟那個年代似乎存在着關聯。1927年似乎是中華民國剛成立,會不會那個時候出了什麼事情呢。看來搞計算機不但要上知天文下知地理。歷史知識也得過關啊。當然,如果沒有這些也不要緊。有搜索引擎就行。
大家都知道,中國古代我們的老祖宗是怎麼計時的嗎?大家應該不陌生,很多的武俠片,歷史劇中大家都經常聽到“天乾物燥,小心火燭”的更夫的慣用口令。沒錯,古代都是用更來表示晚上時間的。戌時作爲一更,亥時作爲二更,子時作爲三更,丑時爲四更,寅時爲五更。三更就是半夜---晚上12點。古代的24小時是分成12個時辰。每個時辰是用1個地支來表示的(共12個地支,和12生肖對應)。每個時辰是2小時。但時辰是怎麼計算的呢。
去過北京故宮的朋友應該還有印象,在大殿前有個叫日晷的計時工具,它把一個時辰平均分成了八份,一份叫做一刻。所以午時三刻大概就是11點45分左右,這個時候,太陽最高,人的影子最短。一天當中“陽氣”最盛的時候。,這個時候是鬼魂最不敢出來的時候。古代的人們就是用這個進行時間的記錄的。說到這裏,大家可能會有疑問,日晷計時需要有太陽啊。晚上怎麼辦呢。特別是更夫他們是靠什麼知道時間,並通知其他人的呢。關鍵就在“銅壺滴漏”。 這種計時裝置最初只有兩個壺,由上壺滴水到下面的受水壺,液麪使浮箭升起以示刻度。保持上壺的水位恆定是滴漏計時準確的關鍵。打更人就是在家守着這個“銅壺滴漏”,一到時間就出去打更告訴其他人。因爲水受溫度影響比較明顯,後來這個滴漏也有改進。開始用水銀,後來就用細沙。沙漏就這樣誕生了。
似乎扯得有點遠,我們回到近代吧。1912年之前,中國各地並沒有統一的標準時間。在王朝時代,國家的標準曆法由皇庭頒佈,而中國傳統曆法同時依賴於日月兩個天體的運動,並以實際天文觀測爲準,因此歷時標準都以朝廷所在地(欽天監的觀測點)的經緯爲準。民國7年(1918年),中央觀象臺提出將全國劃分爲5個標準時區 。
l 中原時區(GMT+8),(東經120度經線之時刻爲標準);北京、江浙等
l 隴蜀時區(GMT+7),(東經105);陝西、四川、雲南、貴州等:
l 回藏時區(GMT+6),(東經90);蒙古、甘肅、青海等。
l 崑崙時區(GMT+5:30),(東經82);新疆及西藏之西部等。
l 長白時區(GMT+8:30),(東經127);東北。
民國17年(1928年),國民政府統一中國,原中央觀象臺的業務由南京政府中央研究院的天文研究所和氣象研究所分別接收。天文研究所編寫的歷書基本上沿襲中央觀象臺的做法,仍將全國劃分爲5個標準時區,只是在一些特別的天文時間點上,不再使用北平的地方平時(local mean time,簡稱LMT),而改以南京所在的標準時區的中原時區標準時替代(中原時區的標準時刻,由位於上海租界的徐家彙觀象臺提供,再由電報總局、鐵路局以電報形式或者廣播電臺形式將標準時刻傳遞到各地所屬機構,這個時間就是我們現在使用的UTC+8時區的時間,它和北平的LMT時間相比差了5分52秒)。其中,地方平時就是指,在指定的經度範圍內使用一致時間的地方太陽時,他的一致性僅取決於測量用的鐘表準確性。地方平時從19世紀初期開始逐漸被採用,這些地區都不再使用地方太陽時或日晷的時間。這個時間段就是1912年~1927年之間。從1928年起,相當於對我國的中原時區(北京,上海,江蘇等)的時間進行了校正,和國際接軌了。
到了1935年,全國統一使用UTC+8時區的時間,但仍然分成之前的5個時區。當然在抗戰時期,曾經一度以隴蜀時區作爲全國的統一時間。抗戰結束後即又恢復中原時區。
新中國成立的頭幾年,全國各地所用的時間比較混亂。五時區還在實行,但是北京時間的概念已經出來了。初期使用的“北京時間”不是我們今天理解的北京時間,也就是說它不是標準時,甚至不是北京地方的平太陽時(以太陽連續兩次經過某地之下中天的平均時間間隔,更爲精確,地球自轉傾角和橢圓軌道決定了每天的視太陽時是不一樣的),而是北京地方的視太陽時。(視太陽時:也就是真實的太陽連續兩次經過某地相同之中天的時間間隔)。建國初期,百廢待興,出現這樣的情況是可以理解的。到1954年,標準時(UTC+8)的北京時間終於明確下來。至此,除了西藏和新疆外,其他地區都劃歸爲東八區。當然香港澳門,臺灣因爲地理位置原因,也正巧都屬於東八區範圍內。再補充一點:北京時間並不是在北京確定的,而是由位於陝西臨潼的中國科學院國家授時中心原子鐘確定的。
現在即使是西藏和新疆,官方(政府機關,學校,單位)都使用北京時間(只要是中國境內)。當然當地人在家裏有可能會使用當地時間。經度上烏魯木齊屬於東6區,要比北京時間晚2個小時。
前面也提到過80年底搞過6年的夏令時。簡單總結一下:
1986年至1991年,每年從4月中旬的第一個星期日2時整(北京時間)到9月中旬第一個星期日的凌晨2時整(北京夏令時)。除1986年因是實
行夏時制的第一年,從5月4日開始到9月14日結束外,其它年份均按規定的時段施行。
政府動員實行夏令時的初衷是爲節約能源而早睡早起。
但1992年4月5日後不再實行。中國不適合實行夏令時的原因:
中國西部的四川、雲南、新疆等地實行的都是北京時間,相當於全年實行夏令時。所以,夏時制只對東北和華北起作用。
中國大多數的平民都已習慣北京時間。實行夏令時對於他們來說難以接受,覺得這是多此一舉。
夏時制使鐵路和航班需要每年修改時間表,造成麻煩。
目前全世界範圍內,俄羅斯2011年3月27日開始永久使用夏令時。美國從三月到11月實行夏令時。歐洲除了冰島之外都執行夏令時。 日本,韓國,臺灣地區和我國現在不執行夏令時。
說到這裏,其實謎底早已經揭開了。1928年1月1日0時0分0秒,上海改使用UTC+8時區替代了原來的本地時間。變成了1927年12月31日12時54分8秒,從而有5分52秒的差距。我們可以到專業的時間認定網站去查看。
http://www.timeanddate.com/time/zone/china/shanghai
Time Changes in Shanghai over the years
在1927年之前,“Nochanges, UTC +8:05:52 hours all of the period”
1927年之後,“Nochanges, UTC +8 hours all of the period”
終於多出來的5分52秒終於找到了。
所以說再1927年以前的時間中,每年:08:00:00~08:05:51(北京時間)這段時間實際上是不存在的。那個年代中國地區使用的是本地時間,本地時間比GMT足足少了5分52秒。
這個事情我明白了一個道理。很多時候,計算機的問題,被一定非得通過計算機的方法才能解決。或者說,換個思路,換個角度,很多看起來很難解釋的問題也能夠迎刃而解的。希望和大家一起從中得到啓示,所以特撰此文,共享之。