Reputation: 54806
I must be doing something fundamentally wrong here. I've got very simple code:
private static final long MILLIS_PER_YEAR = 1000 * 60 * 60 * 24 * 365;
//...
public long getAge() {
long millis = System.currentTimeMillis() - this.getBirthdate().getTime();
System.out.println("Computed age: " + (millis / MILLIS_PER_YEAR) + ", birthdate=" + this.getBirthdate() + ", birthdateMillis="
+ this.getBirthdate().getTime() + ", now=" + new Date() + ", nowMillis=" + System.currentTimeMillis()
+ ", elapsedMillis=" + millis);
return millis / MILLIS_PER_YEAR;
}
...but it's giving some completely incorrect output:
Computed age: 248, birthdate=2001-01-01 10:00:00.0, birthdateMillis=978307200000, now=Fri Aug 10 16:56:48 EST 2012, nowMillis=1344581808173, elapsedMillis=366274608173
Computed age: 184, birthdate=2004-01-01 10:00:00.0, birthdateMillis=1072915200000, now=Fri Aug 10 16:56:48 EST 2012, nowMillis=1344581808173, elapsedMillis=271666608173
If I run the same computation manually (or by using Google), I get the correct result (within a reasonable allowance, due to the fact that there are slightly more than 365 days in a real year).
How is it that the same math is producing such nonsensical output in this code?
Upvotes: 3
Views: 243
Reputation: 308031
The value of MILLIS_PER_YEAR
is wrong. It's 1471228928
instead of the desired 31536000000
.
Look at the calculation of the value: all participating values are int
values (numeric, non-decimal constants are int
-values by default in Java). This means that the result of the calculation will be an int
value as well. But the desired value is bigger than an int
can hold, so you'll have an overflow.
To ensure that the caluclation is done on long
values, simply make at least one of the values a long (by appending the L
suffix):
private static final long MILLIS_PER_YEAR = 1000L * 60 * 60 * 24 * 365;
Upvotes: 13