Adjust the start and end dates
The key is to adjust your dates.
- Move the starting date to the first of the month
- Move the ending date to the first of the following month
We move the ending to the next month after because the Half-Open approach is commonly used when considering spans of time. Half-Open means the beginning is inclusive while the ending is exclusive. So lunch hour runs from 12:00
to 13:00
but does not include the 61st minute of 1 PM. A week runs from Monday to Monday
, for seven days not including that second Monday.
So a span running from the first of January to the first of March is two months rather than three because we run up to, but do not include, that last date, the first of March.
java.time
The java.time classes built into Java 8 and later make easier work of this.
For date-only values, without a time-of-day and without a time zone, use the LocalDate
class.
LocalDate start = LocalDate.parse( "2016-01-31" );
LocalDate stop = LocalDate.parse( "2016-02-01" );
To adjust, use a TemporalAdjuster
. Implementations can be found in the TemporalAdjusters
class (note the plural 's'). We need firstDayOfMonth
and firstDayOfNextMonth
.
LocalDate startAdjusted = start.with( TemporalAdjusters.firstDayOfMonth() );
LocalDate stopAdjusted = stop.with( TemporalAdjusters.firstDayOfNextMonth() );
Now use the ChronoUnit
class to calculate elapsed whole months.
long calendarMonthsTouched = ChronoUnit.MONTHS.between( startAdjusted , stopAdjusted );
span: 2016-01-31/2016-02-01
calendarMonthsTouched: 2
See this code live in IdeOne.com.