搞過Java的都知道1970/1/1問題,沒錯!咱們java時間戳就是這天開始,這個我相信你們都知道歷史緣由:java
——spa
最初計算機操做系統是32位,而時間也是用32位表示。32位能表示的最大值是2147483647。另外1年365天的總秒數是31536000,2147483647/31536000 = 68.1,也就是說32位能表示的最長時間是68年,而實際上到2038年01月19日03時14分07秒,便會到達最大時間,過了這個時間點,全部32位操做系統時間便會變爲10000000 00000000 00000000 00000000,也就是1901年12月13日20時45分52秒,這樣便會出現時間迴歸的現象,不少軟件便會運行異常了。操作系統
到這裏,我想問題的答案已經出來了:由於用32位來表示時間的最大間隔是68年,而最先出現的UNIX操做系統考慮到計算機產生的年代和應用的時限綜合取了1970年1月1日做爲UNIX TIME的紀元時間(開始時間),至於時間迴歸的現象相信隨着64爲操做系統的產生逐漸獲得解決,由於用64位操做系統能夠表示到292,277,026,596年12月4日15時30分08秒,相信咱們的N代子孫,哪怕地球毀滅那天都不用愁不夠用了,由於這個時間已是千億年之後了。code
Date date = new Date(0); System.out.println(date);
出來的結果:Thu Jan 01 08:00:00 CST 1970orm
今天,又遇到一個因歷史問題而產生的坑:對象
// .Net中Datetime的起始時間 String doNetStartTime = "0001-01-01T00:00:00.0000000+08:00"; // 利用joda(jdk8中已包含) datetime轉換成一個GregorianCalendar對象 GregorianCalendar gregorianCalendar = DateTime.parse(doNetStartTime).toGregorianCalendar(); // 將這個calendar對象的date屬性用simpledateformat格式化打印出來 SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSXXX"); System.out.println(format.format(gregorianCalendar.getTime()));
結果倒是:0001-01-03T00:00:00.000+08:00ip
爲啥日期變成了3號?網上搜到一箇中文靠譜解釋:開發
——get
在java.time包中,像全部主要的時間/日期類同樣,LocalDate是固定於單個曆法系統的:由ISO-8601標準定義。form
ISO-8601曆法系統是事實上的世界民用曆法系統,也就是公曆。平年有365天,閏年是366天。閏年的定義是:非世紀年,能被4整除;世紀年能被400整除。爲了計算的一致性,公元1年的前一年被當作公元0年,以此類推。
採用這套曆法,第一個影響就是,ISO-8601的日期沒必要跟GregorianCalendar一致。在GregorianCalendar中,凱撒歷和格里高利曆之間有一個轉換日,通常默認在1582年10月15日。那天以前,用凱撒歷:每4年一個閏年,沒有例外。那天以後,用格里高利曆,也就是公曆,擁有稍微複雜點的閏年計算方式。
既然凱撒歷和格里高利曆之間的轉換是個歷史事實,那爲何新的java.time開發包不參照它呢?緣由就是,如今使用歷史日期的大部分Java應用程序,都是不正確的,繼續下去,是個錯誤。這是爲何呢?當年,羅馬的梵蒂岡,把曆法從凱撒歷改換成格里高利曆的時候,世界上大部分其餘地區並無更換曆法。好比大英帝國,包括早期的美國,直到大約200後的1752年9月14日才換曆法,沙俄直到1918年2月14日,而瑞典的歷法轉換更是一團糟。所以,實際上,對1918以前的日期,解釋是至關多的;僅相信擁有單一轉換日的GregorianCalendar,是不靠譜的。因此LocalDate中沒有這種轉換,就是一個合理的選擇了。應用程序須要額外的上下文信息,才能在凱撒歷和格里高利曆間,精確的解釋特定的歷史日期。
英文好的同窗能夠直接看JDK中java.util.GregorianCalendar的jdoc,太長,這裏不貼了···
總結:
Joda-time是對ISO8601國際標準化組織的國際標準的一個實現,1582年10月15日以前是沒有Gregorian曆法的(又譯做格林尼治日曆時間),因此使用Joda-time把一個曆法外的時間用該曆法進行轉換時,結果將是不正確的。
參考內容:
維基百科 https://en.wikipedia.org/wiki/ISO_8601