java.time
The Joda-Time project is now in maintenance mode. The team advises migration to the java.time classes.
LocalDate
As in Joda-Time, a LocalDate
represents a date-only value without time-of-day and without a time zone.
LocalDate start = LocalDate.of ( 2012 , Month.JANUARY , 31 );
LocalDate stop = LocalDate.of ( 2012 , Month.MARCH , 1 );
Establish the place to hold our results.
long countMonths = 0;
YearMonth
The YearMonth
class represents, well, a year and a month. This is the conduit to considering whole months, as you want, rather than number of days.
YearMonth ymStart = YearMonth.from ( start );
YearMonth ymStop = YearMonth.from ( stop );
This YearMonth
class has methods for comparison such as isAfter
, isBefore
, and equals
.
The ChronoUnit
class can calculate elapsed months between a pair of Temporal
objects. The YearMonth
class fortunately implements Temporal
and works with ChronoUnit
.
if ( ymStart.isAfter ( ymStop ) ) {
// Handle error condition. Unexpected input values.
} else if ( ymStart.equals ( ymStop ) ) {
countMonths = 0;
} else { // Else different months.
countMonths = ChronoUnit.MONTHS.between ( ymStart , ymStop );
}
Dump to console.
System.out.println ( "start: " + start + " | stop: " + stop + " | countMonths: " + countMonths );
start: 2012-01-31 | stop: 2012-03-01 | countMonths: 2
Half-Open
The results above are based on the Half-Open approach to defining a span of time where the beginning is inclusive while the ending is exclusive. This approach is commonly used with date-time work, including throughout the java.time classes.
So, for example, lunch period starts at the first moment of the noon hour and runs up to, but not including, the first moment of 1 PM.
Another example: A week would start on a Monday and run up to, but not including, the following Monday. Or in this case, a pair of year-months from January and going up to, but not including, March; they yield a span of 2 months.
I believe using the Half-Open approach throughout your code leads to more clarity and less bugs. But if you or your users demand otherwise, add one to the results above.
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old date-time classes such as java.util.Date
, .Calendar
, & java.text.SimpleDateFormat
.
The Joda-Time project, now in maintenance mode, advises migration to java.time.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations.
Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport and further adapted to Android in ThreeTenABP (see How to useā¦).
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval
, YearWeek
, YearQuarter
, and more.