65

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

#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
  • 2038年 1 月 19 日星期二 03:14:07
  • 1901 年12 月 13 日星期五 20:45:52

函数 ctime()、gmtime() 和 localtime() 都将时间值作为参数,该时间值表示自 Epoch 以来的时间(以秒为单位)(UTC 时间 00:00:00,1970 年 1 月 1 日;参见 time(3))。

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

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

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 PST
  • 2008 年 8 月 30 日星期六 12:02:40 PDT
  • 8 月 16 日星期六 23:12:55 PST 292278994
  • 12 月 02 日星期日 08:47:04 PST 292269055

但是 292278994 年呢?

4

10 回答 10

47

我已经编写了 time.h 的可移植替代品(目前只有 localtime()、gmtime()、mktime() 和 timegm()),即使在 32 位机器上也使用 64 位时间。它旨在作为 time.h 的替代品放入 C 项目中。它正在 Perl 中使用,我也打算用它来修复 Ruby 和 Python 的 2038 问题。这为您提供了 +/- 2.92 亿年的安全范围。

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

至于“这在 29 年内不会成为问题”,请仔细阅读此标准答案列表。简而言之,事情发生在未来,有时你需要知道什么时候发生。我也有关于这个问题的介绍,什么不是解决方案,什么是.

哦,别忘了很多时候系统不处理 1970 年之前的日期。事情发生在 1970 年之前,有时你需要知道什么时候。

于 2008-10-20T02:05:35.667 回答
17

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

已知的宇宙有一个有限的过去和未来。[Zebu] 估计当前宇宙的年龄在 10 ** 10 和 2 * 10 ** 10 年之间。宇宙的死亡在 [Nigel] 中估计发生在 10 ** 11 - 年,而在 [Drake] 中估计发生在封闭宇宙(大紧缩)的 10 ** 12 年或 10 ** 14 年一个开放的宇宙(宇宙的热寂)。

 

Y10K 兼容程序可以选择将它们支持的日期范围限制在与宇宙预期寿命一致的日期范围内。Y10K 兼容系统必须接受从过去 10 ** 12 年到未来 10 ** 20 年的 Y10K 日期。Y10K 兼容系统应该接受过去和未来至少 10 ** 29 年的日期。

于 2008-10-25T21:39:42.900 回答
4

Visual Studio 在 Visual Studio 2005 中移至 time_t 的 64 位表示(同时仍保留 _time32_t 以实现向后兼容性)。

只要您小心地始终根据 time_t 编写代码并且不对大小做任何假设,那么正如 sysrqb 指出的那样,您的编译器将解决问题。

于 2008-08-30T18:49:06.350 回答
1

我认为我们应该把漏洞留在里面。然后大约在 2036 年,我们可以开始以大笔资金出售咨询服务来测试一切。毕竟,这不是我们成功管理 1999-2000 过渡期的方式。

我只是在开玩笑!

1999 年,我坐在伦敦的一家银行,当我看到一位顾问开始 Y2K 测试咖啡机时,我感到非常惊讶。我认为,如果我们从那场惨败中学到了什么,那就是绝大多数软件都可以正常工作,而其余的大部分软件如果失败也不会导致崩溃,如果需要,可以在事后修复。因此,除非您正在处理一个非常关键的软件,否则我不会采取任何特殊的预防措施,除非您正在处理一个非常关键的软件。

于 2009-03-25T17:42:44.843 回答
1

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

抱歉,如果你想想你今天写的任何软件的“净现值”,它对 2038 年的软件所做的事情没有影响。几年以上的“投资回报”对于任何软件项目来说都是不常见的,所以通过更快地交付软件而不是想得太远,您可以为您的雇主赚更多的钱。

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

于 2010-10-03T16:33:10.070 回答
0

保留良好的文档,并包含对时间依赖性的描述。我认为没有多少人想过这种转变可能会有多困难,例如 HTTP cookie 将在那个日期中断。

于 2008-10-25T21:15:48.237 回答
0

2038年我们应该做些什么准备?

躲起来,因为世界末日即将来临。

但说真的,我希望编译器(或者准确地说是编写它们的人)能够处理这个问题。他们有将近30年的时间。我希望有足够的时间。

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

于 2009-03-28T07:48:54.200 回答
0

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

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

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

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

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

于 2017-03-07T20:00:38.927 回答
-1

到 2038 年,时间库应该都使用 64 位整数,所以这实际上不会有什么大不了的(在不是完全无人维护的软件上)。

COBOL 程序可能会很有趣。

于 2008-08-30T18:45:45.623 回答
-8

操作词是“应该”。

如果您需要确保面向未来,那么您可以构建自己的日期/时间类并使用它,但如果您认为您编写的内容将用于旧版操作系统,我只会这样做

于 2008-08-30T18:47:16.337 回答