简体   繁体   English

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

[英]What's going on with Java's Date class? Is this a known bug?

I know Date is mostly deprecated, but I still use it form time to time (less code than using Calendar ). 我知道Date大多已被弃用,但我仍然不时地使用它(代码少于使用Calendar )。 I came across a truly bizarre bug, and I'm wondering if anyone can explain this to me. 我遇到了一个真正奇怪的错误,我想知道是否有人可以向我解释这个问题。

This code, which adds 24 days to the current time: 此代码在当前时间增加了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);

gives this correct output: 给出正确的输出:

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

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

while this code, which adds 25 days: 这段代码增加了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);

gives this output: 给出这个输出:

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

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

I can understand a difference of hours, even days, but can anyone explain why adding too many milliseconds causes going back in time ?? 我可以理解几小时甚至几天的差异,但任何人都可以解释为什么添加太多毫秒会导致时间倒退 I'm baffled. 我很困惑。

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

you are computing an integer value, and get an overflow. 你正在计算一个整数值,并获得溢出。 if it was 如果它是

25*24*60*60*1000L 25 * 24 * 60 * 60 * 1000L

everything should be fine. 一切都应该没问题。

This isn't a bug in the Date class, it's a case of integer overflow. 这不是Date类中的错误,它是整数溢出的情况。 int s in Java can only be between -2 31 and 2 31 - 1, but 25 × 24 × 60 × 60 × 1000 is greater than 2 31 - 1 so it overflows. Java中的int只能在-2 31和2 31 - 1之间,但25×24×60×60×1000大于2 31 - 1,因此溢出。

If you run 如果你跑

System.out.println(24*24*60*60*1000);
System.out.println(25*24*60*60*1000);

you get the results 你得到了结果

2073600000
-2134967296

If you specify one of the numbers you're multiplying together as a long by adding the L suffix to it, the product will also be a long . 如果您通过向其添加L后缀来指定其中一个数字作为long整数,则该产品也将是一个long整数。 long values can go up to 2 63 - 1 so you won't get overflow unless you're adding a lot of days to your Date s. long值可以达到2 63 - 1,因此除非你在Date添加很多天,否则你不会溢出。 For example, 例如,

System.out.println(25L*24*60*60*1000);

gives you 给你

2160000000

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM