7gooo6
7gooo6

Reputation: 33

Joda-Time: Strange behavior for leap year in Period calculation

The result of Period for the following 2 cases (starting from 2016 Feb 28/29 to 2017 Mar 1) are same as each other.

Could you please help to explain this strange behavior?

Case 1: 2016 Feb 28 to 2017 Mar 1

Calendar start1 = Calendar.getInstance();
start1.set(2016, Calendar.FEBRUARY, 28, 0, 0, 0);
Calendar end1 = Calendar.getInstance();
end1.set(2017, Calendar.MARCH, 1, 0, 0, 0);
Interval i1 = new Interval(new DateTime(start1.getTime()), new DateTime(end1.getTime()))
System.out.println(i1.toPeriod());

result: P1Y1D


Case 2: 2016 Feb 29 to 2017 Mar 1

Calendar start2 = Calendar.getInstance();
start2.set(2016, Calendar.FEBRUARY, 29, 0, 0, 0);
Calendar end2 = Calendar.getInstance();
end2.set(2017, Calendar.MARCH, 1, 0, 0, 0);
Interval i2 = new Interval(new DateTime(start2.getTime()), new DateTime(end2.getTime()))
System.out.println(i2.toPeriod());

result: P1Y1D

Upvotes: 3

Views: 1081

Answers (1)

Jim Garrison
Jim Garrison

Reputation: 86774

Consider

public static void main(String[] args) throws Exception
{
    LocalDate start1 = LocalDate.of(2016, Month.FEBRUARY, 28);
    LocalDate start2 = LocalDate.of(2016, Month.FEBRUARY, 29);
    LocalDate end    = LocalDate.of(2017, Month.MARCH,     1);
    Period    year   = Period.ofYears(1);

    System.out.println(start1);
    System.out.println(start2);
    System.out.println(end);
    System.out.println(start1.plus(year));
    System.out.println(start2.plus(year));
    System.out.println(start1.until(end));
    System.out.println(start2.until(end));
}

Output

2016-02-28
2016-02-29
2017-03-01
2017-02-28
2017-02-28
P1Y1D
P1Y1D

This may not be how you'd like for it to work, but it seems the implementations are consistent.

What exactly does it mean to add 1 year to February 29th? It can be equally taken as "The last day in February" or the start date plus 365 days. The latter definition causes a problem for days prior to February 29th of a leap year:

February 1 2016 + 1 year == January 31 2017
February 1 2017 + 1 year == February 1 2018

which would confuse people.

This is a quirk of the way our calendar works, and the existing behavior seems to minimize (but not eliminate) the dates for which the behavior is "surprising".

Upvotes: 1

Related Questions