I know Date
is mostly deprecated, but I still use it form time to time (less code than using 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:
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
future = Sun Jul 05 10:50:09 IDT 2009
while this code, which adds 25 days:
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
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.
Design flaws include: Its name is misleading: it doesn't represent a Date , it represents an instant in time. So it should be called Instant – as its java. time equivalent is.
The class Date represents a specific instant in time, with millisecond precision. Prior to JDK 1.1, the class Date had two additional functions. It allowed the interpretation of dates as year, month, day, hour, minute, and second values. It also allowed the formatting and parsing of date strings.
Both Date and Calendar are mutable, which tends to present issues when using either in an API. FYI, the terribly troublesome old date-time classes such as java. util. Date , java.
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
everything should be fine.
This isn't a bug in the Date class, it's a case of integer overflow. int
s in Java can only be between -231 and 231 - 1, but 25 × 24 × 60 × 60 × 1000 is greater than 231 - 1 so it overflows.
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
. long
values can go up to 263 - 1 so you won't get overflow unless you're adding a lot of days to your Date
s. For example,
System.out.println(25L*24*60*60*1000);
gives you
2160000000
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With