Melih Altıntaş
Melih Altıntaş

Reputation: 2535

Java date class interesting

End date was being computed to be earlier than the start date

Date startDate = new Date();
Date endDate = new Date(startDate.getTime() + (24 * 3_600_000 * 42));
System.out.println(startDate);
System.out.println(endDate);

output :

Tue Sep 17 01:46:31 EEST 2013
Mon Sep 09 08:43:43 EEST 2013

why the output is not correct ?

Upvotes: 2

Views: 482

Answers (4)

Basil Bourque
Basil Bourque

Reputation: 339679

The Answer by rgettman is specifically correct. More generally, you are using terribly flawed legacy classes that since your post were supplanted by the modern java.time classes defined in JSR 310.

java.time

FYI, java.util.Date now replaced by java.time.Instant.

We can replace your code with the following.

Instant.now().plus( Duration.ofDays( 42 ) )

No need for your math.

The java.time.Instant class represents a moment, a point on the timeline, as seen with an offset from UTC of zero hours-minutes-seconds. This is the same meaning as the java.util.Date replaced by Instant.

The Duration class represents a span of time unattached to the timeline on the scale of hours-minute-seconds. If you want to represent your 42 days as forty-two chunks of 24-hour time rather than calendar days, use Duration.

Instant now = Instant.now() ;
Duration fortyTwoGenericDays = Duration.ofDays( 42 ) ;
Instant fortyTwoGenericDaysLater = now.plus( fortyTwoGenericDays ) ;

To see the result of code above through the clock and calendar of a particular time zone, apply a ZoneId to get a ZonedDateTime.

ZoneId z = ZoneId.of( "Europe/Berlin" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;

Generate text in standard ISO 8601 format by calling toString.

String output = zdt.toString() ;

Upvotes: 1

Theodoros Chatzigiannakis
Theodoros Chatzigiannakis

Reputation: 29233

The number you're trying to add is 24 * 3600000 * 42 which is equal to 3,628,800,000. This is larger than 2,147,483,647 which is the maximum value that can be represented with the given data type. What you're experiencing is an overflow, meaning that after crossing the maximum value, the number loops back to its lowest value, which is in the negative. Therefore, you're adding a negative value to the date.

Upvotes: 0

nanofarad
nanofarad

Reputation: 41281

24 * 3600000 * 42 is 3,628,800,000 which does not fit into an int. Rollover occurs. Force the use of a long by casting one of the factors:

24L * 3600000 * 42

Upvotes: 0

rgettman
rgettman

Reputation: 178303

Your integer arithmetic has overflowed. The maximum possible value of an int is 2147483647 or Integer.MAX_VALUE (a little over 2 billion), but multiplying your integer literals would yield 3628800000 (about 3.6 billion). The result is a negative number (-666167296), and an earlier date.

Try casting one of your literals as a long to force long arithmetic (or use long literals):

( (long) 24 * 3600000 * 42)

or

(24L * 3600000 * 42)

This operation is well within the range of long values (max value 9223372036854775807, over 9 quintillion).

Upvotes: 11

Related Questions