Joda Years.yearsBetween issue?

1.4k views Asked by At

I have 2 DateTime values: date1 = "1492-10-12" and date2 = "1992-10-12". When I use Years.yearsBetween(date1, date2).getYears(), I get 499. I was expecting 500. If I use date1 = "1892-10-12" and date2 = "1992-10-12", then I get 100.

In diagnosing the issue, I found that the problem first occurs when I have 2 DateTime values: date1 = "1492-10-12" and date2 = "1583-10-12". I get 90 years when I should be getting 91. When date2 = "1582-10-12" or earlier, then the calculation is correct.

I am assuming that this is because the Gregorian calendar started in 1582, but I'm not sure why we are 1 year off. Any ideas? Is 499 theoretically correct or is there a problem with with yearsBetween when 1582 falls within the start and end dates?

My code looks like:

Date date1 = null;
Date date2 = null;
try {
    date1 = sdf.parse("1492-10-12");
    date2 = sdf.parse("1992-10-12");
} 
catch (ParseException e) {
    e.printStackTrace();
}
int yrs = computeDiffInYears(date1, date2);  ?? yrs = 499

private static int computeDiffInYears(Date date1, Date date2) {
    DateTime dt1 = (new DateTime(date1));
    DateTime dt2 = (new DateTime(date2));
    return Years.yearsBetween(dt1, dt2).getYears();
}

UPDATE: If I rewrite the method, computeDiffInYears, as suggested by Anarki as:

private static int computeDiffInYears(Date date1, Date date2) {
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    DateTime dt1 = new DateTime(sdf.format(date1));
    DateTime dt2 = new DateTime(sdf.format(date2));
    return Years.yearsBetween(dt1, dt2).getYears();
}

then it works correctly

2

There are 2 answers

4
Anarki On BEST ANSWER

You can try this :

public static void main(String[] args) throws ParseException {
    SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");
    Date first = sdf.parse("12-10-1492");
    Date last = sdf.parse("12-10-1992");
    System.out.println(getDiffYears(first, last));
}

public static int getDiffYears(Date first, Date last) {
    Calendar a = getCalendar(first);
    Calendar b = getCalendar(last);
    int diff = b.get(Calendar.YEAR) - a.get(Calendar.YEAR);
    if (a.get(Calendar.MONTH) > b.get(Calendar.MONTH)
            || (a.get(Calendar.MONTH) == b.get(Calendar.MONTH) && a.get(Calendar.DATE) > b.get(Calendar.DATE))) {
        diff--;
    }
    return diff;
}

public static Calendar getCalendar(Date date) {
    Calendar cal = Calendar.getInstance(Locale.US);
    cal.setTime(date);
    return cal;
}

It print 500 witch is correct.

Edit

I just tried this (using Joda) :

public static void main(String[] args) throws ParseException {
    DateTime date1 = new DateTime("1492-10-12");
    DateTime date2 = new DateTime("1992-10-12");
    int yrs = computeDiffInYears(date1, date2);
    System.out.println(yrs);
}

private static int computeDiffInYears(DateTime date1, DateTime date2) {
    return Years.yearsBetween(date1, date2).getYears();
}

It also print 500, but when i try to make a conversion from Date to DateTime it print 499, so you should use only DateTime or Calendar.

1
Gerton On

It could be that Joda does not include the actual "to" date but the day before. in that case the calculation is correct.