大家好,我是小林。
2038 年可能是程序员面临的一道坎,因为这关乎时间戳的问题。
今天就跟大佬唠嗑下这个事情。
文章选自维基百科:2000年问题和2038年问题,感兴趣读者可以自行阅读英文版,信息量更大一些。
千年虫问题,是指由于计算机程序设计的一些问题,使得计算机在处理2000年1月1日以后的日期和时间时,可能会出现不正确的操作,从而可能导致在2000年1月1日零点工作停顿甚至是发生灾难性的结果。
一般来说,由于计算机程序中使用两个数字来表示年份,如1998年被表示为98、1999年被表示为99,而2000年被表示为00。
这样将会导致某些程序在计算时得到不正确的结果,如把“00”误解为1900年。在嵌入式系统中可能存在同样的问题,这有可能导致设备停止运转或者发生更加灾难性的后果。
画外音:这个对于我们程序员来说很好理解,有时候不知道业务发展会怎么样,基于资源和当时的发展情况来考虑,设置空间余量不足,也是常有的事情。
UNIX操作系统是美国AT&T公司贝尔实验室于1969年完成的操作系统,最早Ken Thompson、Dennis Ritchie、Douglas McIlroy于1969年在AT&T贝尔实验室开发。
于1971年首次发布,最初是完全用汇编语言编写。后来在1973年用一个重要的开拓性的方法,Unix被丹尼斯·里奇用编程语言C重新编写,高级语言编写的操作系统具有更佳的兼容性,能更容易地移植到不同的计算机平台。
#ifndef __TIME_T
#define __TIME_T
typedef long time_t;
#endif
在32位系统中time_t实际是一个4字节的有符号长整型,其值表示为从UTC(coordinated universal time)时间1970年1月1日00时00分00秒到当前时刻的秒数。
由于time_t类型长度的限制,它所表示的时间不能晚于2038年1月19日03时14分07秒(UTC),那么当时间戳到达最大值2147483647会发生什么呢?
画外音:要理解2038年问题就必须要理解time_t和signed 32bit的计数。
画外音:这好像还是个大事情,一下子回到了1901年……
在计算机应用上,2038年问题可能会导致某些软件在2038年1月19日3时14分07秒之后无法正常工作。
所有使用POSIX时间表示时间的程序都将受其影响,因为它们以自1970年1月1日经过的秒数(忽略闰秒)来表示时间。
在大部分的32位操作系统上,time_t使用一个有正负号的32位有符号整数存储计算的秒数。依照time_t标准,在此格式能被表示的最后时间是2038年1月19日03:14:07,星期二(UTC)。
一旦超过这个时刻,时间将会绕回且在内部被表示为一个负数,并造成程序无法工作,因为它们无法将此时间识别为2038年,而可能会依个别实现而跳回1970年或1901年。因此可能产生错误的计算及动作。
我们来看下官方的警告:
画外音:官方警告最为真实…
大部分64位操作系统已经把time_t这个系统变量改为64位,但是仍然有数以亿计的32位系统在运行中,特别是许多嵌入式系统。
32位time_t的使用亦被编码于文件格式,例如众所周知的ZIP文件压缩格式。其能存在的时间远比受影响的机器长。
新的64位运算器可以记录至约2900亿年后的292,277,026,596年12月4日15:30:08,星期日(UTC),基本上可以彻底解决时间回环问题。
画外音:换了64位 舒服了…
2038年问题与之前的千年虫问题的杀伤力是不一样的,千年虫属于应用程序的问题,而2038年问题却是系统级的,有更大的杀伤力。
Linux Kernel 5.6 的开发者已经准备好着手解决将在下一个十年到来的 2038 年问题。Linux 5.6 也成为第一个为 32 位系统准备运行到 2038 年之后的主线内核。
至于像MySQL等组件同样面临2038年问题,目前还有17年的时候,我们相信可以应对这次危机。
画外音:还有17年呢,说不定那会儿我都退休了,改造的事情交给年轻人吧…