Funny Bug of the Day (Java)

This took a little while to figure out!

Date startDate = new Date();
Date endDate = new Date(startDate.getTime() + (24 * 3600000 * 42));

This was expected to result with startDate being right now (Feb 20, 2013 5:17:10 PM) and the end date being six weeks later (Apr 3, 2013 6:17:10 PM), but instead end date was being computed to be earlier than the start date… Feb 13, 2013 in fact!What’s going on? The second operand, (24 * 3600000 * 42) which represents the number of milliseconds in a six week span is being evaluated as an integer (32 bit) while the first operand (the timestamp, milliseconds since the epoch) must be stored as a long (64 bit).

The second operand actually pushes beyond the ability for a 32-bit number to be stored properly, but the Java runtime isn’t smart enough to try to coalesce it into a long, so it actually stayed an 32-bit integer, but somehow ended up a negative number because it pushed into the integer’s two-compliment representation and thus turned into a negative number.

I suspect an older programmer is more likely to figure this one out than a younger developer. I know this dates me quite a bit, but I remember programming when an int was 16 bits and 32,767 + 1 actually became -32,768. Well, I guess Java programmers on our their guard when they try to deal with bytes (my kingdom for an unsigned byte in Java!!!) but you don’t expect things like that to happen when you’re working with big values.

Oh, so how to fix the problem? Just put say “24l” instead of “24” and the second operand will start evaluating as a long.

Author: Murray Todd Williams

I live in Austin, Texas. I'm enthusiastic about food, wine, programming (especially Scala), tennis and politics. I've worked for Accenture for over 12 years where I'm a Product Manager for suite of analytical business applications.

Leave a Reply

Your email address will not be published. Required fields are marked *