I am using Joda Time 2.1 library.
I have written a method to compare if a given date is between a date range of not. I want it to be inclusive to the start date and end
Joda-Time has been supplanted by the java.time classes and the ThreeTen-Extra project.
The LocalDateRange
and Interval
classes representing a span-of-time use the Half-Open definition. So, asking if the beginning is contained returns true
.
LocalDateRange.of( // `org.threeten.extra.LocalDateRange` class represents a pair of `LocalDate` objects as a date range.
LocalDate.of( 2018, 8 , 2 ) , // `java.time.LocalDate` class represents a date-only value, without time-of-day and without time zone.
LocalDate.of( 2018 , 8 , 20 )
) // Returns a `LocalDateRange` object.
.contains(
LocalDate.now() // Capture the current date as seen in the wall-clock time used by the people of the JVM’s current default time zone.
)
true
FYI, the Joda-Time project is now in maintenance mode, with the team advising migration to the java.time classes. See Tutorial by Oracle.
Apparently you may care about the date and not the time-of-day. If so, use LocalDate class.
For managing a date range, add the ThreeTen-Extra library to your project. This gives you access to the LocalDateRange class.
That class offers several methods for comparison: abuts
, contains, encloses
, equals
, intersection
, isBefore
, isAfter
, isConnected
, overlaps, span
, and union
.
LocalDateRange r =
LocalDateRange.of(
LocalDate.of( 2018, 8 , 2 ) ,
LocalDate.of( 2018 , 8 , 20 )
)
;
LocalDate target = LocalDate.now( ZoneId.of( "Africa/Tunis" ) ) ; // Capture the current date as seen in the wall-clock time used by the people of a particular time zone.
boolean contains = r.contains( target ) ;
If you care about the date and the time-of-day in a particular time zone, use ZonedDateTime
class.
Start with your LocalDate
, and let that class determine the first moment of the day. The day does not always start at 00:00:00 because of anomalies such as Daylight Saving Time (DST).
Specify a proper time zone name in the format of continent/region
, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland
. Never use the 3-4 letter abbreviation such as EST
or IST
as they are not true time zones, not standardized, and not even unique(!).
ZoneId z = ZoneId.of( "America/Montreal" ) ; // Or "America/New_York", etc.
ZonedDateTime zdtStart = LocalDate.of( 2018, 8 , 2 ).atStartOfDay( z ) ;
ZonedDateTime zdtStop = LocalDate.of( 2018, 8 , 20 ).atStartOfDay( z ) ;
ZonedDateTime zdtTarget = ZonedDateTime.now( z ) ;
Represent a range with the Interval
from ThreeTen-Extra. This class represents a pair of Instant
objects. An Instant
is a moment in UTC, always in UTC. We can easily adjust from our zoned moment to UTC by simply extracting an Instant
. Same moment, same point on the timeline, different wall-clock time.
Instant instantStart = zdtStart.toInstant() ;
Instant instantStop = zdtStop.toInstant() ;
Instant instantTarget = zdtTarget.toInstant() ;
Interval interval = Interval.of( instantStart , intervalStop ) ;
boolean contains = interval.contains( instantTarget ) ;
The best approach to defining a span-of-time is generally the Half-Open approach. This means the beginning is inclusive while the ending is exclusive.
The comparisons in the ThreeTen-Extra
range classes seen above (LocalDateRange
& Interval
) both use Half-Open approach. So asking if the starting date or starting moment is contained in the range results in a true
.
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.
Yes, isAfter
is exclusive, otherwise it should probably have been named isEqualOrAfter
or something similar.
Solution: Use "not before" instead of "after", and "not after" instead of "before".
boolean isBetweenInclusive(LocalDate start, LocalDate end, LocalDate target) {
return !target.isBefore(start) && !target.isAfter(end);
}