I am trying to get a user's age based on their date of birth. The date of birth is given as a string in XML and converted to a Calendar
like so:
final Calendar dob = javax.xml.bind.DatatypeConverter.parseDate(value);
Then I am calculating the user's age like so:
final Calendar now = Calendar.getInstance();
int age = now.get(Calendar.YEAR) - dob.get(Calendar.YEAR);
if (now.get(Calendar.DAY_OF_YEAR) < dob.get(Calendar.DAY_OF_YEAR)) {
--age;
}
I discovered today that if today is the user's birthday (put the party hats away, it isn't mine), the age comes out a year too young. That is, if the user was born in 2000 and today is her birthday, she should be 14 years old, not 13. But when it comes down to it, Java seems to have the DAY_OF_YEAR wrong:
System.out.println(String.format("Today: %d-%d; Birthday: %d-%d", now.get(Calendar.MONTH), now.get(Calendar.DAY_OF_MONTH), dob.get(Calendar.MONTH), dob.get(Calendar.DAY_OF_MONTH)));
// prints: Today: 9-22; Birthday: 9-22
System.out.println(String.format("Today: %d; Birthday: %d", now.get(Calendar.DAY_OF_YEAR), dob.get(Calendar.DAY_OF_YEAR)));
// prints: Today: 295; Birthday: 296
What gives?
An edge condition is causing the issue.
What is special about 2000?
It's a leap year.
Calendar cal = new GregorianCalendar();
cal.set(2000, 11, 31);
System.out.println(cal.getTime());
System.out.println(cal.get(Calendar.DAY_OF_YEAR));
Output:
Sun Dec 31 13:43:28 EST 2000
366
Everything after February 29th is offset by 1 specifically for leap years. Ergo, it's not wrong. In fact, it's working as intended.
You should instead be comparing month and day of month to get around this issue.
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