Half-Open
The other two Answers by davidxxx and by Ole V.V. are both correct and informative.
I want to add about an alternative approach commonly used in date-time work for defining a span of time: Half-Open. In Half-Open approach, the beginning is inclusive while the ending is exclusive. So the months of the first half of the year (Jan, Feb, Mar, Apr, and Jun) are tracked as starting on January 1 and running up to, but not including, July 1.
Sometimes we intuitively use this approach in our daily life. For example, if a classroom of children breaks for lunch from 12:00 noon to 1 PM, the students are expected to be in their seats before the bell strikes at 1 PM. Lunch break runs up to, but does not include, 1 PM.
I believe you will find consistent use of the Half-Open approach makes your code easier to read, debug, and maintain.
The modern java.time classes use this approach in defining a span of time.
LocalDateRange
The Answer by Ole V.V. wisely suggests you look at YearMonth
class to help your work.
Another helpful class is from the ThreeTen-Extra project: org.threeten.extra.LocalDateRange
. You can represent your entire date range in a single object.
You can instantiate with a start date and a Period
of six months.
LocalDateRange ldr = LocalDateRange.of(
LocalDate.of( 2018 , Month.JANUARY , 1 ) ,
Period.ofMonths( 6 )
) ;
Or specify start and stop dates.
LocalDateRange ldr = LocalDateRange.of(
LocalDate.of( 2018 , Month.JANUARY , 1 ) ,
LocalDate.of( 2018 , Month.JULY , 1 ) // Half-open.
) ;
While I don't recommend it, if you insist on using the Fully-Closed approach where beginning and ending are both inclusive, the LocalDateRange
does offer LocalDateRange.ofClosed()
.
LocalDateRange ldr = LocalDateRange.ofClosed( // `ofClosed` vs `of`.
LocalDate.of( 2018 , Month.JANUARY , 1 ) ,
YearMonth( 2018 , Month.JUNE ).atEndOfMonth() // Fully-closed.
) ;
You can get a count of months from a LocalDateRange
via the Period
class.
LocalDateRange ldr = LocalDateRange.of(
LocalDate.of( 2018 , Month.JANUARY , 1 ) ,
Period.ofMonths( 6 )
) ;
Period p = ldr.toPeriod() ;
long totalMonths = p.toTotalMonths() ; // 6
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date
, Calendar
, & SimpleDateFormat
.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.*
classes.
Where to obtain the java.time classes?
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.