2009/02/17 2 Comments
1234567890是个节日,一秒钟的节日。它不是问题,不是错误,也不是BUG。人类使用的计时系统是相当复杂,一般来说,秒是基本单位,60秒为1分钟,60分钟为1小时,24小时是一天……如果计算机也使用相同的方式来计时,那就需要用多个变量来分别存放年月日时分秒,不停的进行进位运算,而且还要处理偶尔的闰年和闰秒以及协调不同的时区。基于“追求简单”的设计理念,UNIX在内部采用了一种最简单的计时方式:
计算从UNIX诞生[1]的UTC时间1970年1月1日0时0分0秒起,流逝的秒数。UTC时间1970年1月1日0时0分0秒就是UNIX时间(UNIX Time)0,UTC时间1970年1月2日0时0分0秒就是UNIX时间86400。这个计时系统被所有的UNIX和UNIX-like系统继承了下来,而且影响了许多非UNIX系统。POSIX标准推出后,这个时间也被称为POSIX时间。
节日和庆祝
也许是因为人类是一种需要精神上的刺激的生物吧,各种历法中都存在着各种拥有不同意义的节日。其中,很多节日仅仅由于日期的特殊性就被赋予了意义,例如公历1月1日的新年,11月11日的光棍节。爱好节日的人们也没有放过UNIX时间:UTC时间2001年9月9日1时46分40秒,UNIX时间迎来了第一个“亿禧年”(Billennium)[2],1000000000。UTC时间2005年3月18日1时58分31秒则是UNIX时间的光棍节,1111111111。刚刚过去的1234567890,对应公历的UTC2009年2月13日23时31分30秒,对东一区以东的时区来说是2月14日情人节,而以西的时区来说却刚好落在黑色星期五。传统上认为黑色星五不吉利的西方媒体,针对此事进行了玩笑性的报道,结果被一些居住在其他时区的人们误读成了“UNIX时间错误”。

丹麦哥本哈根的丹麦UNIX用户群组织庆祝UNIX“亿禧年” 图为当时所用的倒计时公告牌
无独有偶,2012年7月13日也是一个黑色星期五,而那天的UTC时间11时1分20秒对应着UNIX时间0x50000000(十六进制,十进制值是1342177280)。不知到了那个时候,会不会再次有人把它误解为又一次的UNIX时间错误?
未来,2038年问题
UTC时间2033年5月18日3时33分20秒,是UNIX时间的第二个“亿禧年”(Billenniumm),即2000000000。然而,第三个“亿禧年”(Billennium)则不会毫无障碍的来临,在那之前,人们先得解决正在变得著名的2038年问题。和本世纪初的千年虫(Y2K Bug)问题类似,2038年问题(Y2K38 BUG)更隐蔽,而且更难解决。我们知道计算机内部的一切都是二进制的,也就是说1234567890在32位系统的内存里实际上是01001001 10010110 00000010 11010010。这串32位二进制数中,最高位被用来表示正负符号,0代表整数,1代表负数,所以它能表示的最大数字就是01111111 11111111 11111111 11111111,即214748367,对应公历的UTC时间2038年1月19日3时14分7秒。到这天的凌晨3时14分8秒,UNIX时间会溢出并变成10000000 00000000 00000000 00000000(十进制值-214748368),也就是UTC时间1901年12月13日20时45分52秒,引起和千年虫类似的混乱。

2038年问题的动画演示图,可以清楚地看到“溢出”的过程(囧)
救赎:64位系统
2038年问题不仅比千年虫更隐蔽,而且它的原因也更接近系统底层。要解决这个问题,最简单的方式是扩展UNIX时间的长度,用64位数字来表示它。64位二进制数的实际可用位数是63位,最大表示到公历的UTC时间292277026596年12月4日。如果那个时候人类文明还存在的话,公元纪年很可能已经因为太难用而被抛弃了。理想的情况是到2038年,64位系统已经成为主流,从而避免特意去修正这个问题所需要的大量开销。否则,人们就必须把新的64位时间拆分成两部分并分别保存在两个变量里,这是一个麻烦而且效率低下的选择。
[1]:就像很多其他的节日一样,把UNIX的诞生日选在这天只是出于方便。实际上,最早的运行在PDP-7上的UNIX在1969年就已经完成了。
[2]:Billennium实际上是“十亿禧年”,但是这样听起来很奇怪,所以我用“亿禧年”作为暂用名。
声明:本文由Rainarrow原创并相应的拥有著作权,作者据此权利将本文以创作共用[署名-非商业用途-相同方式共享]许可证授权发布。如要查看许可证全文,请访问"http://creativecommons.org/licenses/by-nc-sa/2.5/cn/".
计算从UNIX诞生[1]的UTC时间1970年1月1日0时0分0秒起,流逝的秒数。UTC时间1970年1月1日0时0分0秒就是UNIX时间(UNIX Time)0,UTC时间1970年1月2日0时0分0秒就是UNIX时间86400。这个计时系统被所有的UNIX和UNIX-like系统继承了下来,而且影响了许多非UNIX系统。POSIX标准推出后,这个时间也被称为POSIX时间。
节日和庆祝
也许是因为人类是一种需要精神上的刺激的生物吧,各种历法中都存在着各种拥有不同意义的节日。其中,很多节日仅仅由于日期的特殊性就被赋予了意义,例如公历1月1日的新年,11月11日的光棍节。爱好节日的人们也没有放过UNIX时间:UTC时间2001年9月9日1时46分40秒,UNIX时间迎来了第一个“亿禧年”(Billennium)[2],1000000000。UTC时间2005年3月18日1时58分31秒则是UNIX时间的光棍节,1111111111。刚刚过去的1234567890,对应公历的UTC2009年2月13日23时31分30秒,对东一区以东的时区来说是2月14日情人节,而以西的时区来说却刚好落在黑色星期五。传统上认为黑色星五不吉利的西方媒体,针对此事进行了玩笑性的报道,结果被一些居住在其他时区的人们误读成了“UNIX时间错误”。
丹麦哥本哈根的丹麦UNIX用户群组织庆祝UNIX“亿禧年” 图为当时所用的倒计时公告牌
无独有偶,2012年7月13日也是一个黑色星期五,而那天的UTC时间11时1分20秒对应着UNIX时间0x50000000(十六进制,十进制值是1342177280)。不知到了那个时候,会不会再次有人把它误解为又一次的UNIX时间错误?
未来,2038年问题
UTC时间2033年5月18日3时33分20秒,是UNIX时间的第二个“亿禧年”(Billenniumm),即2000000000。然而,第三个“亿禧年”(Billennium)则不会毫无障碍的来临,在那之前,人们先得解决正在变得著名的2038年问题。和本世纪初的千年虫(Y2K Bug)问题类似,2038年问题(Y2K38 BUG)更隐蔽,而且更难解决。我们知道计算机内部的一切都是二进制的,也就是说1234567890在32位系统的内存里实际上是01001001 10010110 00000010 11010010。这串32位二进制数中,最高位被用来表示正负符号,0代表整数,1代表负数,所以它能表示的最大数字就是01111111 11111111 11111111 11111111,即214748367,对应公历的UTC时间2038年1月19日3时14分7秒。到这天的凌晨3时14分8秒,UNIX时间会溢出并变成10000000 00000000 00000000 00000000(十进制值-214748368),也就是UTC时间1901年12月13日20时45分52秒,引起和千年虫类似的混乱。
2038年问题的动画演示图,可以清楚地看到“溢出”的过程(囧)
救赎:64位系统
2038年问题不仅比千年虫更隐蔽,而且它的原因也更接近系统底层。要解决这个问题,最简单的方式是扩展UNIX时间的长度,用64位数字来表示它。64位二进制数的实际可用位数是63位,最大表示到公历的UTC时间292277026596年12月4日。如果那个时候人类文明还存在的话,公元纪年很可能已经因为太难用而被抛弃了。理想的情况是到2038年,64位系统已经成为主流,从而避免特意去修正这个问题所需要的大量开销。否则,人们就必须把新的64位时间拆分成两部分并分别保存在两个变量里,这是一个麻烦而且效率低下的选择。
[1]:就像很多其他的节日一样,把UNIX的诞生日选在这天只是出于方便。实际上,最早的运行在PDP-7上的UNIX在1969年就已经完成了。
[2]:Billennium实际上是“十亿禧年”,但是这样听起来很奇怪,所以我用“亿禧年”作为暂用名。
声明:本文由Rainarrow原创并相应的拥有著作权,作者据此权利将本文以创作共用[署名-非商业用途-相同方式共享]许可证授权发布。如要查看许可证全文,请访问"http://creativecommons.org/licenses/by-nc-sa/2.5/cn/".
Leave a comment
大理石平台 

2009/02/19 15:24
第一次听到”一秒钟的节日“。
说节“日”是因为习惯,因为没有“节秒”这种词语……
翎峋 

2009/02/17 18:34
这个问题好奇特哦,说不定到时候已经是128位系统了。
所以正常来说应该没有问题~
分页: 1/1
1
1

