Linux时钟会在2038年1月19日3:14:08失败吗?


23

我对此有些担心。这就是所谓的“ 2038年问题”。从12.04开始,Linux内核或Ubuntu是否准备好处理此后的日期?


8
您是否尝试过将时钟设置为2038年1月19日3:14:07之类的时间并等待一秒钟?
gertvdijk

2
假设存在此问题,但尚未解决。永远不会支持12.04,因此您和所有其他人都将拥有更新的发行版,直到这种情况发生为止,因为两者之间存在很多年。更新很容易。这些更新之一肯定会包含一个修复程序。因此,没有理由要担心,但这确实是一个有趣的问题。
2013年

3
该错误已得到修复。
ThePiercingPrince

系统时钟不会(无论如何不是在最近的内核上);一些数据结构(以及使用它的程序)可能表现出异常行为。我认为,这将是嵌入式设备的问题-嵌入式设备运行当前代码的可能性要小得多。
Piskvor

1
@hmayag:我不是在想“烤面包机”,更像是“交通灯控制器”。这些东西比消费级电子产品更坚固耐用,并且很容易超过使用寿命(更换零件,但可能无需升级)-IIRC,在2000年以后,这种1980年代的电子产品存在一些问题。
2013年

Answers:


13

不,它不会失败。在最坏的情况下,从程序员的角度来看,它将按预期工作:它将重置为1901-12-13 20:45:52日期:

在此处输入图片说明

如果您在这种情况下不会更新当前的发行版,则可以。“ 更新很容易。这些更新之一肯定会包含一个修复程序。 ”例如chocobai说。

我记得在2000年之前16位机器上也有同样的问题,直到最后都没问题。

维基百科的解决方案:

设计为在64位硬件上运行的大多数操作系统已经使用带符号的64位time_t整数。使用带符号的64位值将引入一个新的环绕日期,该日期比宇宙的估计年龄大二十倍:从现在起大约2920亿年,即12月4日星期日15:30:08,为292,277,026,596。日期进行计算的能力受到以下事实的限制:tm_year使用带符号的32位int值(从1900年开始)。这将一年的最大值限制为2,147,485,547(2,147,483,647 + 1900)。尽管这解决了执行程序的问题,但并没有解决在二进制数据文件中存储日期值的问题,二进制数据文件中的许多数据都采用严格的存储格式。对于在兼容层下运行的32位程序,它也不能解决问题,对于将时间值错误地存储在类型以外的变量中的程序,它也可能无法解决问题time_t

我在64位上使用Ubuntu 13.04,并且出于好奇,我将时间手动更改为2038-01-19 03:13:00。03:14:08之后,什么都没发生:

2038-01-19 03:14:08之前的日期和时间 2038-01-19 03:14:08之后的日期和时间

因此,无需担心此问题。

更多关于:


9
如果重置,它将失败,因为“失败”是指“不工作或工作不正确”。
ThePiercingPrince

1
@LinuxDistance从您的角度来看这会发生。但是从程序员的角度来看,它将按预期工作:它将重置。玛雅历法的终结也是如此:世界并没有因此而失败。
RaduRădeanu13年

10
我不同意?从程序员的角度看时钟不应该复位,所以它失败
Nanne

3
评论中的讨论毫无意义。问题是“ Linux内核或Ubuntu是否准备在此之后处理日期?”。好吧,它无法处理此类日期,因此在此问题的上下文中失败。
gertvdijk

2
@gertvdijk“ 当前/实际的 “ Linux内核或Ubuntu准备在此之后处理日期吗?”
RaduRădeanu13年

7

您可以使用以下Perl脚本检查计算机的时间是否崩溃:

#!/usr/bin/perl
use POSIX;
$ENV{'TZ'} = "GMT";
for ($clock = 2147483641; $clock < 2147483651; $clock++) {
    print ctime($clock);
}

如果您的计算机没问题,您将获得以下信息:

Tue Jan 19 03:14:01 2038
Tue Jan 19 03:14:02 2038
Tue Jan 19 03:14:03 2038
Tue Jan 19 03:14:04 2038
Tue Jan 19 03:14:05 2038
Tue Jan 19 03:14:06 2038
Tue Jan 19 03:14:07 2038       <-- Last second in 32-bit Unix systems
Tue Jan 19 03:14:08 2038
Tue Jan 19 03:14:09 2038
Tue Jan 19 03:14:10 2038

如果您的计算机像我的计算机,它将像这样缠绕:

Tue Jan 19 03:14:01 2038
Tue Jan 19 03:14:02 2038
Tue Jan 19 03:14:03 2038
Tue Jan 19 03:14:04 2038
Tue Jan 19 03:14:05 2038
Tue Jan 19 03:14:06 2038
Tue Jan 19 03:14:07 2038
Fri Dec 13 20:45:52 1901
Fri Dec 13 20:45:52 1901
Fri Dec 13 20:45:52 1901

它也可以这样做:

Tue Jan 19 03:14:01 2038
Tue Jan 19 03:14:02 2038
Tue Jan 19 03:14:03 2038
Tue Jan 19 03:14:04 2038
Tue Jan 19 03:14:05 2038
Tue Jan 19 03:14:06 2038
Tue Jan 19 03:14:07 2038
Tue Jan 19 03:14:07 2038
Tue Jan 19 03:14:07 2038
Tue Jan 19 03:14:07 2038

我认为您是在这里测试Perl,而不是核心的真正操作系统。还是您使用ctime
gertvdijk 2013年

@gertvdijk好吧,它在打补丁的计算机上提供了第一个输出,而我的Ubuntu笔记本电脑提供了第二个输出,而第三个则来自我的Debian服务器。我实际上并没有编写代码,而是以完全相同的形式在Internet上编写的。
SkylarMT

2
确认。如果您使用的是64位计算机,则可以。此外...到2038年,我们中只有谁仍将运行32位计算机?
jrg 2013年

1
我一直在寻找这个可以向同事说明2038问题的方法,发表上述评论两年后,我毫不怀疑在2038年我们将有32台机器出现故障。啊,青春的乐观。
jrg 2015年

@詹姆斯,也许有些不知不觉。届时可能会在IoT设备中嵌入嵌入式32位Linux。世界末日?不,在某些地方有麻烦吗?绝对是
Falken教授支持Monica

3

我在1996年就此撰写并发表了一篇简短的论文。其中包括一个简短的C程序来演示它。我还向David Mills发送了有关NTP(网络时间协议)类似问题的电子邮件。在我的Ubuntu 14.04 64位笔记本电脑上,perl代码没有受到限制,因此必须修改基础的64位库。

但是,运行我的长期测试代码确实显示出时间回溯到UNIX Epoch。因此,过去的32位代码并非一帆风顺。

我1996年的论文《 UNIX时间将在2038年用完!自2000年以来一直在我的网站上。1998年,在“ 2000年Y2K千年计算最佳实践” ISBN 0136465064中发布了名为“ UNIX时间”的变体。


2

64位Linux已经准备就绪,至少在您谈论核心OS接口时(各个应用程序当然仍然可以搞砸它)。传统上,将time_t定义为“ long”的别名,而在64位linux上,“ long”是64位。

对于32位Linux(以及64位Linux上32位二进制文​​件的兼容层)的情况要乐观得多。它已损坏,并且在不破坏所有现有二进制文件的情况下对其进行修复并非易事。一大堆API使用time_t,并且在许多情况下,它是作为数据结构的一部分嵌入的,因此不仅必须复制API,而且它们使用的数据结构也必须相同。

即使存在一定程度的向后兼容性,也需要重建所有要获取正确时间的二进制文件,以使用新的64位时间接口。

已经完成了一些工作(例如,参见https://lwn.net/Articles/643234/http://www.sourceware.org/ml/libc-alpha/2015-10/msg00893.html),但是我们距离完整的解决方案还有很长的路要走。尚不清楚是否会存在Y2K38安全的通用32位发行版。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.