Java的Date类发生了什么?这是一个已知的错误?

Yuv*_*val 5 java date

我知道Date大部分已被弃用,但我仍然不时地使用它(代码少于使用代码Calendar).我遇到了一个真正奇怪的错误,我想知道是否有人可以向我解释这个问题.

此代码在当前时间增加了24天:

long nowL = System.currentTimeMillis();
Date now = new Date(nowL);
System.out.println("now = "+now);
Date future = new Date(nowL+ 24*24*60*60*1000);
System.out.println("future = "+future);
Run Code Online (Sandbox Code Playgroud)

给出正确的输出:

now = Thu Jun 11 10:50:09 IDT 2009

future = Sun Jul 05 10:50:09 IDT 2009

这段代码增加了25天:

long nowL = System.currentTimeMillis();
Date now = new Date(nowL);
System.out.println("now = "+now);
Date future = new Date(nowL+ 25*24*60*60*1000);
System.out.println("future = "+future);
Run Code Online (Sandbox Code Playgroud)

给出这个输出:

now = Thu Jun 11 10:51:25 IDT 2009

future = Sun May 17 17:48:37 IDT 2009

我可以理解几小时甚至几天的差异,但任何人都可以解释为什么添加太多毫秒会导致时间倒退?我很困惑.

mfx*_*mfx 27

25*24*60*60*1000 = 2160000000 = 0x80BEFC00

你正在计算一个整数值,并获得溢出.如果它是

25*24*60*60*1000L

一切都应该没问题.

  • TRWTF是编译器不会警告你关于常量的整数溢出. (6认同)

Luk*_*ard 5

这不是Date类中的错误,它是整数溢出的情况.intJava中的s只能在-2 31和2 31 - 1之间,但25×24×60×60×1000大于2 31 - 1,因此溢出.

如果你跑

System.out.println(24*24*60*60*1000);
System.out.println(25*24*60*60*1000);
Run Code Online (Sandbox Code Playgroud)

你得到了结果

2073600000
-2134967296
Run Code Online (Sandbox Code Playgroud)

如果您将其中一个数字相乘,则将其long添加到L后面,该产品也将是a long. long价值可以达到2 63 - 1,所以你不会溢出,除非你为你的s 增加了很多Date.例如,

System.out.println(25L*24*60*60*1000);
Run Code Online (Sandbox Code Playgroud)

给你

2160000000
Run Code Online (Sandbox Code Playgroud)