問題由來:之前在JS中學到Date對象時,時間是從1970年1月1日0時開始的,現在看Java居然也是這樣,就很好奇,為什么時間都用這個時間點來計算。然后百度了下,發現有一個很好的帖子描述了這個問題。現在轉載過來,以備忘。
看完后自己的理解就是,早期Unix等機器都是32位,那么表示的時間長度有限,只能從1901年到2038年,那么過了2038年時間就會回到1901年。這樣就有問題。不過這個最后隨著64位機器的誕生就解決了。因為時間可以表示
2^63/86400 ~ 1E14(天) ~ 2.92E11(年)
大約是2920億年。 足夠了o/
具體還是把這個分析過程貼在這里,以免那個那個網頁消失了。哈哈,相信簡書會存活很久吧。
以下是轉載
為什么編程語言以及數據庫要從1970年1月1日開始計算時間
今天在看Python API時,看到time模塊:
The epoch is the point where the time starts. On January 1st of that year, at 0 hours,the “time since the epoch” is zero. For Unix, the epoch is 1970. To find out what the epoch is, look at gmtime(0).
定義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點。
我想以上問題如果作為面試題,也能難倒一批人了.
轉自:http://blog.sina.com.cn/s/blog_61352f210100geai.html,原文標題:為什么編程語言以及數據庫要從1970年1月1日開始計算時間,發表時間:2009-11-20 13:48:46。
Linux程式設計-29.時間處理
UNIX及Linux的時間系統是由「新紀元時間」Epoch開始計算起,單位為秒,Epoch則是指定為1970年一月一日凌晨零點零分零秒,格林威治時間。
目前大部份的UNIX系統都是用32位元來記錄時間,正值表示為1970以後,負值則表示1970年以前。我們可以很簡單地計算出其時間領域:
2^31/86400(s) = 24855.13481(天) ~ 68.0958(年)
1970+68.0958 = 2038.0958
1970-68.0958 = 1901.9042
時間領域為[1901.9042,2038.0958]
。
準確的時間為2038年一月十八日星期一晚上十點十四分七秒。那一刻,時間將會轉為負數,變成1901年十二月十三日黑色星期五下午三點四十五分五十二秒,然後Jason就會跑出來用斧頭砸掉您的電腦。
這就是所謂的UNIX 2038 BUG
,或者您也可戲稱為Jason hatchet bug
。在大部份的UNIX上,并沒有所謂Y2K問題,不過都有2038年問題。
在一些64位元的平臺上,例如Digital Alpha、SGI、Sparc等等,則用64位元來表示時間。
2^63/86400 ~ 1E14(天) ~ 2.92E11(年) 。大約是2920億年。
因此,使用64位元的電腦可能會有 Armageddon bug 的問題。屆時位於獵戶座旋臂的太陽,已經是黑矮星或暗黑物質,獵戶座旋臂大概也已經被重力波震斷,銀河系大概則已經變成小型似星體了。
雖然許多人認為UNIX的2038年問題會隨著科技的進步,而將電腦逐步汰換成64位元電腦,因此無須擔心。但我個人相信,在2038年,依然會有許多狀況出現。因為,就事實而言,目前許多UNIX系統都有足夠的能力服役到2038年而毫無問題。因此,如果有意添購電腦主機,而且有預期會使用到那個時候,最好是選購64位元電腦,確認只有世界末日問題(除非您想要把資料流傳給下一個宇宙,那就要另當別論了)。
(果然剛才訪問這篇文章的原帖,已經404)
深入分析Linux內核源碼
以上我們了解了RTC(實時時鐘、硬件時鐘)和OS時鐘(系統時鐘、軟時鐘)。下面我們具體描述OS時鐘。OS時鐘是由可編程定時/計數器產生的輸出脈沖觸發中斷而產生的。輸出脈沖的周期叫做一個“時鐘滴答”。計算機中的時間是以時鐘滴答為單位的,每一次時鐘滴答,系統時間就會加1。操作系統根據當前時鐘滴答的數目就可以得到以秒或毫秒等為單位的其他時間格式。
定義“時間基準”的目的是為了簡化計算,這樣計算機中的時間只要表示為從這個時間基準開始的時鐘滴答數就可以了。