Unix在1969年诞生之初就采用了一个简单的设计——以离之最近的新年作为计时零点记录流逝的秒数。后来这个计时系统被所有的Unix和Unix-like系统继承了下来。
沈迦勒/编
雨璇/配图
【Q】刘克澄问:为啥程序猿写日子都要换算成和1970-1-1的天数?
【A】
沈迦勒答:人们现在使用的计时系统是公历,计算较为复杂:秒是基本单位,60秒为1分,60分为1小时,24小时是一天…如果计算机内部也使用相同的方式
来计时,
就需要多个变量来分别存放年月日时分秒,不停进位,而且还要处理偶尔的闰年和闰秒以及协调不同的时区。Unix在1969年诞生之初就采用了一个简单的设
计——以离之最近的新年(1970-1-1
00:00:00,公历UTC时间,下同)作为计时零点记录流逝的秒数。后来这个计时系统被所有的Unix和Unix-like系统继承了下来,而且影响
了许多非Unix系统,便于跨平台交流数据。POSIX标准,即可移植操作系统接口(Portable Operating System
Interface of
Unix)推出后,这个时间也被称为POSIX时间。因此在程序中如果时间变量为空、或没有被正确地初始化,只是简单地赋一个0值的话,计算结果便会跳到
1970-1-1;这也是现在的所有操作系统上你无法把时间调到1970-1-1之前的原因。
2001-9-9
01:46:40,Unix时间迎来了第一个Billennium(十亿禧年),即十进制的1,000,000,000。2005-3-18
01:58:31则是Unix时间的光棍节,1,111,111,111。2033-5-18
3:33:20是第二个Billenniumm,然而第三个则不会毫无障碍的来临,在那之前,人们先得解决著名的2038年问题。和本世纪初的千年虫
(Y2K Bug)问题类似,2038年问题(Y2K38
Bug)更隐蔽、更底层、更难解决。计算机内部用来存储时间的32位二进制数中,最高位被用来表示正负符号,所以它能表示的最大数字是2^31-1,即
2147483647, 对应2038-1-19 03:14:07。到这天的凌晨03:14:08,
Unix时间会溢出并变成十进制的-2147483648,也就是1901-12-13
20:45:52,引起和千年虫类似的混乱。这将会影响到所有使用这个计时方式的32位系统及其程序语言。要解决这个问题,最简单的方式是扩展计时的长度
至64位。但愿那时64位系统已成为主流,就可以避免特意去修正这个问题所需要的巨大开销。沈迦勒/编·图灵的苹果