0

I use LocalDate (ThreeTenABP) to calculate the period between to given dates. When I use 01/01/2018 as the first and 12/31/2018 as the second date, Period.between gives the following result:

00 years
11 months
30 days

IMHO this is wrong, since a full year has 12 months. I tried to add one day. Then I get:

00 years
11 months
31 days

I would need a reliable method to get the real amount of full months within a given period.

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
DMP
  • 23
  • 4

2 Answers2

1

If you look at the Javadoc for Period.between(), it tells you that the end date is exclusive (meaning: not counted).

The start date is included, but the end date is not. The period is calculated by removing complete months, then calculating the remaining number of days, adjusting to ensure that both have the same sign.

I wrote this code, and it appears to function as I would expect...

LocalDate d1 = LocalDate.of(2018, 1, 1);
LocalDate d2 = LocalDate.of(2018, 12, 31);
Period p1 = Period.between(d1, d2);
System.out.println(p1.getYears() + " years, " + p1.getMonths() + " months, " + p1.getDays() + " days");
// Prints: 0 years, 11 months, 30 days

Adding one day, making it 2019-01-01, gives me one year:

LocalDate d3 = LocalDate.of(2019, 1, 1);
Period p2 = Period.between(d1, d3);
System.out.println(p2.getYears() + " years, " + p2.getMonths() + " months, " + p2.getDays() + " days");    
// Prints: 1 years, 0 months, 0 days

Edit:

If you just add one day to the calculated Period object, you are really just adding a day, not recalculating the period as the between method would. Here's the code from Period which does plusDays():

public Period plusDays(long daysToAdd) {
    if (daysToAdd == 0) {
        return this;
    }
    return create(years, months, Math.toIntExact(Math.addExact(days, daysToAdd)));
}

If you follow the create call, it really just adds one day to the days counter, it doesn't recalculate anything. To properly add a day to a period, recalculate it with different endpoints as I have above.

Todd
  • 30,472
  • 11
  • 81
  • 89
  • Thank you for the quick answer. I knew that the end date is excluded, hence I tried to add one day using .plusDays(1) , but I still get a different result. 0 years, 11 month and 31 days. – DMP Jan 20 '18 at 18:42
0

The reliable method is:

    LocalDate begin = LocalDate.of(2018, Month.JANUARY, 1);
    LocalDate end = LocalDate.of(2018, Month.DECEMBER, 31);
    Period inclusive = Period.between(begin, end.plusDays(1));
    System.out.println(inclusive);

This prints

P1Y

Voilà, a period of one year. Adding 1 day to the end date makes the end date inclusive (since now it’s the day after the end date that is exclusive).

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161