Java Calendar.DAY_OF_YEAR is sometimes disabled by one
I am trying to get the age of a user based on their date of birth. Date of birth is specified as a string in XML and is converted to the Calendar
following:
final Calendar dob = javax.xml.bind.DatatypeConverter.parseDate(value);
Then I calculate the age of the user like this:
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;
}
Today I found that if today is the user's birthday (take away the parties, this is not mine), the age goes a year too young. That is, if the user was born in 2000, and today is her birthday, she must be 14 years old, not 13. But when it comes down to that, Java seems to have a DAY_OF_YEAR error:
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?
source to share
The edge problem is causing the problem.
What's special about 2000?
This is 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 01:43:28 PM EST 2000
366
Everything after February 29 is offset by 1 specifically for leap years. Ergo, it's not like that. In fact, it works as intended.
Instead, you should compare the month and day of the month to work around this issue.
source to share