今天在寫 new Date () 時,無意中發現了一個很有意思的方法,getTime()
,百度了一下,有人說是計算從 1970 年 1 月 1 日至今的毫秒數
為什麼要是 1970 年呢?
new Date().getTime();
// xxxxxxxxxxx
這個起源於 unix 的誕生,因為 Unix 在 1969 年被開發出來,1971 年正式發布,在這之前沒有機器會需要來表示 1970-01-01-00:00:00 之前的時間,後面的語言很多就沿用了這一習慣,js 只是也沿用了這種習慣而已。
當然,這一做法現在看來是很有問題的,例如不方便用它表示更早的時間而且精度有限。
定義 time 從 1970 年 1 月 1 日開始,忽然想到在 JAVA 裡,Oracle 資料庫時間也是從 1970 年 1 月 1 日開始計算。
比如 java 類代碼:
Date date = new Date(0);
System.out.println(date);
// 打印出來的結果:Thu Jan 01 08:00:00 CST 1970也
是 1970 年 1 月 1 日,實際上時分秒是 0 點 0 分 0 秒(這裡打印出來是 8 點,稍後會作解釋)。
為什麼這個時間會定義在 1970 年 1 月 1 日這個時候呢?
於是開始了 Google,中文網頁根本找不到答案。於是試著搜索英文關鍵字,在 Sun java 論壇總算找到準確的帖子:
http://forums.sun.com/thread.jspa?threadID=595140&start=15
其中有一個回覆:
I suspect that Java was born and raised on a UNIX system.
UNIX considers the epoch (when did time begin) to be midnight, January 1, 1970.
是說 java 起源於 UNIX 系統,而 UNIX 認為 1970 年 1 月 1 日 0 點是時間紀元。
但這依然沒很好地解釋 "為什麼",出於好奇,繼續 Google,總算找到了答案:
http://en.wikipedia.org/wiki/Unix_time
這裡的解釋是:
最初計算機操作系統是 32 位,而時間也是用 32 位表示。
System.out.println(Integer.MAX_VALUE);
2147483647
Integer 在 JAVA 內用 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 的紀元時間(開始時間),而 java 自然也遵循了這一約束。
至於時間回歸的現象相信隨著 64 位操作系統的產生逐漸得到解決,因為用 64 位操作系統可以表示到 292,277,026,596 年 12 月 4 日 15 時 30 分 08 秒,相信我們的 N 代子孫,哪怕地球毀滅那天都不用愁不夠用了,因為這個時間已經是千億年以後了。
最後一個問題:
上面 System.out.println (new Date (0)),打印出來的時間是 8 點而非 0 點,原因是存在系統時間和本地時間的問題,其實系統時間依然是 0 點,只不過我的電腦時區設定為東 8 區,故打印的結果是 8 點。