关于Unix:我们应该为2038年做些什么?

关于Unix:我们应该为2038年做些什么?

What should we do to prepare for 2038?

我想我今天编写的某些软件将在30年内使用。但我也知道,很多时间都是基于UNIX的传统,即把时间公开为自1970年以来的秒数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <stdio.h>
#include <time.h>
#include <limits.h>

void print(time_t rt) {
    struct tm * t = gmtime(&rt);
    puts(asctime(t));
}

int main() {
    print(0);
    print(time(0));
    print(LONG_MAX);
    print(LONG_MAX+1);
}

执行将导致:

  • 1970年1月1日星期四00:00:00
  • 2008年8月30日星期六18:37:08
  • 周二1月19日03:14:07 2038
  • 星期五12月13日20:45:52 1901

The functions ctime(), gmtime(), and localtime() all take as an argument a time value representing the time in seconds since the Epoch (00:00:00 UTC, January 1, 1970; see time(3) ).

我想知道,作为程序员,在这方面是否有任何积极主动的事情要做?还是我们相信,将来所有软件系统(又称操作系统)将如何进行神奇的升级?

更新看来确实64位系统对此是安全的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import java.util.*;

class TimeTest {
    public static void main(String[] args) {
        print(0);
        print(System.currentTimeMillis());
        print(Long.MAX_VALUE);
        print(Long.MAX_VALUE + 1);
    }

    static void print(long l) {
        System.out.println(new Date(l));
    }
}
  • 1969年12月31日星期三16:00:00
  • 2008年8月30日星期六12:02:40
  • 周六8月16日23:12:55 PST 292278994
  • 星期日十二月02 08:47:04 PST 292269055

但是292278994年呢?


我已经编写了可替换的time.h(目前仅是localtime(),gmtime(),mktime()和timegm()),即使在32位计算机上也使用64位时间。打算将它放入C项目中,以代替time.h。它正在Perl中使用,我也打算用它来解决Ruby和Python的2038问题。这为您提供+/- 292百万年的安全范围。

您可以在y2038项目中找到代码。请随时将任何问题发布到问题跟踪器。

至于"再过29年这将不再是问题",请仔细阅读这份标准答案清单。简而言之,将来会发生某些事情,有时您需要知道何时。我也有关于问题的介绍,什么不是解决方案,什么是解决方案。

哦,别忘了很多时间系统都不处理1970年之前的日期。东西发生在1970年之前,有时您需要知道何时。


您可以始终实施RFC 2550,并且永远安全;-)

The known universe has a finite past and future. The current age of
the universe is estimated in [Zebu] as between 10 ** 10 and 2 * 10 **
10 years. The death of the universe is estimated in [Nigel] to occur
in 10 ** 11 - years and in [Drake] as occurring either in 10 ** 12
years for a closed universe (the big crunch) or 10 ** 14 years for an
open universe (the heat death of the universe).

Y10K compliant programs MAY choose to limit the range of dates they
support to those consistent with the expected life of the universe.
Y10K compliant systems MUST accept Y10K dates from 10 ** 12 years in
the past to 10 ** 20 years into the future. Y10K compliant systems
SHOULD accept dates for at least 10 ** 29 years in the past and
future.


Visual Studio在Visual Studio 2005中移动到time_t的64位表示形式(为了向后兼容,仍然保留_time32_t)。

只要您谨慎地始终使用time_t编写代码,并且不假设大小有关任何内容,那么正如sysrqb所指出的那样,问题将由编译器解决。


我认为我们应该留出漏洞。然后在2036年左右,我们可以开始以大量资金出售咨询服务,以测试所有内容。毕竟,这不是我们成功管理1999-2000年过渡的方式。

我只是在开玩笑!

1999年,我坐在伦敦的一家银行里,当我看到一位顾问开始对计算机进行Y2K测试时,我感到非常惊讶。我认为,如果我们从那桩惨败中学到了什么,那是因为绝大多数软件都可以正常工作,并且如果软件失败,其余大多数软件都不会崩溃,可以在事件发生后进行修复。因此,我不会采取任何特殊的预防措施,直到更近的时间为止。


考虑到我的年龄,我认为我应该为我的养老金和所有部门支付很多钱,所以其他人将不得不安装该软件!

抱歉,如果您考虑今天编写的任何软件的"净现值",那么该软件在2038年的表现将没有任何影响。几年以上的"投资回报率"对于任何软件项目都是罕见的,因此通过更快地发布软件,而不是想得太早,您可以为您的老板赚很多钱。

唯一常见的例外是必须预测未来的软件,到2038年,抵押贷款报价系统已经存在问题。


我从事嵌入式工作,我想我将在此处发布我们的解决方案。 我们的系统使用32位元,并且我们现在销售的产品有30年的保修期,这意味着它们将遇到2038年的错误。 将来升级不是解决方案。

为了解决这个问题,我们将内核日期设置为比当前日期早28年。 这不是一个随机的偏移量,而28年无疑是一周中几天重新匹配的时间。 例如,我在星期四写这篇文章,而下一次3月7日是28年。

此外,与我们系统上的日期进行交互的所有应用程序都会将系统日期(time_t)转换为自定义的time64_t,并将28年的偏移量应用于正确的日期。

我们制作了一个自定义库来处理此问题。 我们正在使用的代码基于此:https://github.com/android/platform_bionic

因此,使用此解决方案,您可以轻松地额外购买28年。


What should we do to prepare for 2038?

躲起来,因为末日就要来了。

但是,认真的说,我希望编译器(或者确切地说是编写它们的人)能够解决这个问题。他们已经快30年了。我希望有足够的时间。

我们从什么时候开始准备Y10K?是否有任何硬件制造商/研究实验室研究过最简单的方法来迁移到我们因此而必须拥有的任何新技术?


保留良好的文档,并包括对时间依赖性的描述。我认为没有多少人考虑过这种过渡的难度,例如,HTTP cookie将会在该日期中断。


到2038年,时间库都应全部使用64位整数,因此这实际上并没有什么大不了的(对于并非完全没有维护的软件)。

虽然COBOL程序可能很有趣。


手术用语是"应该"。

如果您需要确保面向未来,那么您可以构建自己的日期/时间类并使用它,但是只有当您认为您编写的内容将在旧版OS上使用时,我才会这样做。


推荐阅读