zishu's blog

zishu's blog

一个热爱生活的博主。https://zishu.me

為什麼getTime()返回1970年至今的毫秒?

今天在寫 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 點。

載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。