【问题标题】:When will System.currentTimeMillis() overflow?System.currentTimeMillis() 什么时候会溢出?
【发布时间】:2011-02-28 00:55:13
【问题描述】:

我有一个网络应用程序,它使用一个很长的时间戳来订购东西。我的 web 应用后端恰好是用 java 编写的,所以我正在使用:

long timestamp = System.currentTimeMillis();

这会在哪一年(大约)失败?我的意思是,在某个时候,long 的范围会溢出,对吧?我们可能都早已死去,但我只是好奇。它会再次像 y2k 一样吗?我可以为此做些什么准备?可笑,我知道,只是好奇!

【问题讨论】:

    标签: java time overflow year2038


    【解决方案1】:

    它会溢出

    System.out.println(new Date(Long.MAX_VALUE));
    

    打印出来的

    Sun Aug 17 03:12:55 GMT-04:00 292278994
    

    这是在 2.92 亿年之后。我想说,同时有 大量 时间来发明解决方案。老实说,我不指望人类能够幸存下来。与age of the world 相比,我们只存在几秒钟,而且不会花费很长时间。

    【讨论】:

      【解决方案2】:

      尝试运行此代码:

      System.out.println(new Date(Long.MAX_VALUE));
      

      根据您的语言环境打印类似这样的内容:

      Sun Aug 17 17:12:55 EST 292278994
      

      未来很长,不用担心溢出。

      【讨论】:

        【解决方案3】:

        您的网络应用似乎不太可能在美国东部标准时间 8 月 17 日星期日 17:12:55 EST 292278994 仍然存在 (由他人计算)。那时您似乎更不可能仍然负责 Web 应用程序。 (如果你还是要负责的话,你以后可能会得到更高的报酬,所以先让它滑下来,以后再收大钱吧:)

        很可能系统时钟被错误地设置为某个古怪的值。您可以相对轻松地为此做好准备 - 下面的伪代码

        long reasonableDate ( )
        {
             long timestamp = System.currentTimeMillis();
             assert timestamp after 2010AD : "We developed this web app in 2010.  Maybe the clock is off." ;
             assert timestamp before 10000AD : "We don't anticipate this web app will still be in operation in 10000AD.  Maybe the clock is off." ;
             return ( timestamp ) ;
        }
        

        如果您在其中任何一个断言被触发时还活着,那么您可能会因修复系统时钟或更改断言(视情况而定)向您的客户收取大笔费用。

        【讨论】:

          【解决方案4】:

          “我可以为此做些什么准备?”

          好吧,您可以在棺材上装上最新最好的 IT 设备/极客玩具。但不知何故,我认为它们在公元 292,278,994 年会有点“过时”。到那时你会对他们感到厌烦。

          请注意,您将有足够的时间从头开始重写操作系统以使用 128 位时钟。这听起来像是一个消磨时间的有趣项目。 :-)

          【讨论】:

            【解决方案5】:

            Java long 的最大值是2^63 - 1,如果你把那么多毫秒换算成实际的时间单位,你会发现计数器会在大约 2.9 亿年后溢出。所以不用担心 ;-) 如果还有人在附近运行计算机,我敢肯定他们届时将切换到 128 位时间计数器(或选择一个新纪元)。

            【讨论】:

              【解决方案6】:

              这些答案中的错误是假设您正在运行的系统是 64 位并返回自 1970 年以来的 64 位表示。Linux 使用 32 位表示并且溢出是在 2038 年。

              参考Year 2038 problem

              【讨论】:

              • 问题似乎是关于 Java 的。文档将结果指定为自 UTC 1970 年 1 月 1 日午夜以来的毫秒长值,无论底层系统是什么。
              • 您认为在 32 位 JRE 中究竟会发生什么?遗产是一回事。
              • 即使在 32 位 JRE 上,Long 也是 64b。见stackoverflow.com/a/18017796/16673
              • 恐怕你错了。 System.currentTimeInMillis 是如何实现的并不重要,它必须遵循规范,这是一个自 UTC 1970 年 1 月 1 日午夜开始的毫秒数的长值。剩下的具体实现是粒度,通常比毫秒粗得多,但范围由规范给出。
              • 您可以检查各种操作系统的实现,例如在JDK OS LinuxJDK OS Windows 中(搜索javaTimeMillis)。您将看不到这些溢出,它们都使用不限于 32b 毫秒的系统调用。如果您知道发生溢出的某些特定平台,请显示出来。
              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2015-05-25
              • 1970-01-01
              • 1970-01-01
              • 2020-04-29
              相关资源
              最近更新 更多