问题由来:之前在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。操作系统根据当前时钟滴答的数目就可以得到以秒或毫秒等为单位的其他时间格式。
定义“时间基准”的目的是为了简化计算,这样计算机中的时间只要表示为从这个时间基准开始的时钟滴答数就可以了。
网友评论