计算机千年虫问题

2000年问题

2000年问题(英语:Year 2000 Problem),在英文中也被简称为Y2K,在中国大陆及香港常被称为千年虫问题,台湾则称千禧蟲危机,是指由于当时的计算机程序在日期表达上的设计问题,从而导致计算机会误读在2000年后的一些日期,并进一步导致计算机出现错误所引起的计算机问题,当时的计算机程序普遍采用6位数字来存储时间,只显示四位数字后的两位数字,但这又会导致计算机系统紊乱,使其无法区分2000年与1900年,从而导致了误读问题,并导致计算机紊乱。2000年问题可能会威胁到那些运行在重要行业中的计算机与大量社会基础设施,甚至影响到政府部门与军队。从而导致停水、断电,银行瘫痪,最极端的情况下,它甚至可能会导致核电厂发生事故,核武器与导弹失控以及交通与通信的中断,并最终引发灾难性的后果。

这个悬挂于南特中央理工学院的电子标志将2000年1月3日错误显示为了1900年1月3日。

Bug_de_l'an_2000

但最终,在2000年问题引起社会广泛重视后,它得到了足够的关注与处理,最终在规模庞大的修复行动后,它没有在新千年到来之际引起全球电脑系统的大规模瘫痪。

程序问题本源

两千年问题始于1960年代,当时计算机内存和外部存储介质的成本很高,大多数数据处理需要借助穿孔卡片。为了节省硬件成本,葛丽丝·霍普在Harvard Mark I上以6位数字来存储时间,即年、月、日各两位。这个习惯被COBOL继承下来,传播到整个计算机程序界。

当时的编程语言,如COBOL和RPG,使用ASCII和EBCDIC编码表示数据。如果用四位数字表示年份,就要多占用存储介质空间,使成本增加;因此为了节省存储空间,计算机系统的编程人员采用两位数字表示年份。随着计算机技术的迅猛发展,存储介质的价格逐步下降,但在计算机系统中使用两位数字来表示年份的做法却由于惯性思维而被沿袭下来;对大多数程序员来说,他们并不认为所编写的软件会持续使用很多年。

具体来讲,两千年问题要解决的事项包括以下几个要点:

软件在特定的日期会否出现运作错误。要留意的日期包括以下几个日子:

  • 1999年1月1日
  • 1999年4月9日(1999年的第99日)
  • 1999年9月9日
  • 1999年12月31日
  • 2000年1月1日
  • 2000年2月28日
  • 2000年2月29日
  • 2025年1月1日(昭和100年问题)
  • 2038年1月19日(参见2038年问题)
  • 2099年1月1日
  • 2099年4月9日
  • 2099年9月9日
  • 2099年12月31日
  • 2111年11月11日

软件会不会利用特定的日期格式来表示档案完结,或档案已删除。 软件会否出现错误的日期,如“19100年”或“3000年”。 两千年问题是由鲍伯·贝默在1958年第一次提出的。在其后的二十年里,他用了很大的努力,希望政府、企业和国际组织(如IBM和ISO)来关注这个问题,但反响寥寥。直到2000年将要到来的时候,人们才感觉到两千年问题的紧迫性。于是社会和政府都投入了大量的人力和物力来避免发生大规模的计算机灾难。而从现在来看,这些努力也获取了相应的成果。

总结:本质问题在于程序设计之初的历史背景与环境因素有关,由于存储空间的有限,加上忽略了业务膨胀速度所导致的问题。现在这样的情况也不断的在上演,程序员们对于业务的考虑大多也仅局限于10年内的业务发展考量。

2038问题

在计算机应用上,2038年问题可能会导致某些软件在2038年1月19日3时14分07秒之后无法正常工作。所有使用POSIX时间表示时间的程序都将受其影响,因为它们以自1970年1月1日经过的秒数(忽略闰秒)来表示时间[1]。这种时间表示法在类Unix(Unix-like)操作系统上是一个标准,并会影响以其C编程语言开发给其他大部分操作系统使用的软件。在大部分的32位操作系统上,此“time_t”数据模式使用一个有正负号的32位整数(signed int32)存储计算的秒数。依照此“time_t”标准,在此格式能被表示的最后时间是2038年1月19日03:14:07,星期二(UTC)。超过此一瞬间,时间将会“绕回”(wrap around)且在内部被表示为一个负数,并造成程序无法工作,因为它们无法将此时间识别为2038年,而可能会依个别实现而跳回1970年或1901年。因此可能产生错误的计算及动作。

有少数的情况下,在制定规格时,特别规定以无正负号的32位整数(unsigned int32)存储POSIX时间,因此错误会被延后到2106年。例如比特币区块链中的区块时间戳记,就是以这种方法存储。[2][3]

目前并没有针对现有的CPU/操作系统搭配的简单解决方案。直接将POSIX时间更改为64位模式将会破坏对于软件、数据存储以及所有与二进制表示时间相关的部分的二进位兼容性。更改成无符号的32位整数则会影响许多与两时间之差相关的程序。不过,那时使用32位系统的计算机可能会很少。

大部分64位操作系统已经把time_t这个系统变量改为64位宽。不过,其他现有架构的改动仍在进行中,不过预期“应该可以在2038年前完成”。然而,直到2006年,仍然有数以亿计的32位系统在运行中,特别是许多嵌入式系统。相对于一般电脑科技18至24个月的革命性更新,嵌入式系统可能直至使用寿命终结都不会改变。32位time_t的使用亦被编码于文件格式,例如众所周知的ZIP文件压缩格式。其能存在的时间远比受影响的机器长。

新的64位运算器可以记录至约2900亿年后的292,277,026,596年12月4日15:30:08,星期日(UTC)。

图片

32位操作系统

在计算机应用上,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位操作系统

大部分64位操作系统已经把time_t这个系统变量改为64位,但是仍然有数以亿计的32位系统在运行中,特别是许多嵌入式系统。

32位time_t的使用亦被编码于文件格式,例如众所周知的ZIP文件压缩格式。其能存在的时间远比受影响的机器长。

新的64位运算器可以记录至约2900亿年后的292,277,026,596年12月4日15:30:08,星期日(UTC),基本上可以彻底解决时间回环问题。

对比2038问题与千年虫问题

2038年问题与之前的千年虫问题的杀伤力是不一样的,千年虫属于应用程序的问题,而2038年问题却是系统级的,有更大的杀伤力。

Linux Kernel 5.6 的开发者已经准备好着手解决将在下一个十年到来的 2038 年问题。Linux 5.6 也成为第一个为 32 位系统准备运行到 2038 年之后的主线内核。

至于像MySQL等组件同样面临2038年问题,目前还有17年的时候,我们相信可以应对这次危机。