Calendar.fieldDifference() bug

Description

When I tried to calculate the month difference of the two extremes of Calendar, a RuntimeException was thrown.
Code:

Calendar cal1 = Calendar.getInstance();
cal1.set(Calendar.EXTENDED_YEAR, Calendar.getActualMinimum(Calendar.EXTENDED_YEAR));
cal1.set(Calendar.MONTH, Calendar.getActualMinimum(Calendar.MONTH));
cal1.set(Calendar.DATE, Calendar.getActualMinimum(Calendar.DATE));
cal1.set(Calendar.MILLISECONDS_IN_DAY, 0);

Calendar cal2 = Calendar.getInstance();
cal1.set(Calendar.EXTENDED_YEAR, Calendar.getActualMaximum(Calendar.EXTENDED_YEAR));
cal1.set(Calendar.MONTH, Calendar.getActualMaximum(Calendar.MONTH));
cal1.set(Calendar.DATE, Calendar.getActualMaximum(Calendar.DATE));
cal1.set(Calendar.MILLISECONDS_IN_DAY, 0);

// RuntimeException although it should return around 140,000,000, small enough to fit in int.
int dif = cal1.fieldDifference(cal2.getTime(), Calendar.MONTH);

Looking at the code of fieldDifference() in Calendar class,
I found out that there is not a defined behavior of add() method when it overflows.
In my case, where I used GregorianCalendar, add() method cycled around Calendar limits
and the code of fieldDifference() could not catch it and stop iteration,
so it overflowed.

Activity

Show:
Anonymous
November 12, 2018, 6:15 AM

Sorry, I just noticed a typo I made in the code.
The above code does not throw an exception.
In the second Calendar creation, the 4 cal1.set() calls should be cal2.set() calls.
The RuntimeException is thrown then.

Yoshito Umaoka
February 21, 2019, 2:54 AM

Reproduced with the code

As the author pointed out, Calendar#fieldDifference() trying to add maximum positive int in Calendar#add() as delta, and it triggers integer overflow, because it tries to set current field value + delta, that exceeds maximum positive int. I cannot fix this design issue for 64.1. I'll revisit this issue for a later release.

Assignee

Yoshito Umaoka

Reporter

Anonymous

Components

Labels

None

Reviewer

None

Priority

assess

Time Needed

None

Fix versions

Configure