I have a series of ranges with start dates and end dates. I want to check to see if a date is within that range.
Date.before() and Date.after() seem to be a little awkward to use. What I really need is something like this pseudocode:
boolean isWithinRange(Date testDate) { return testDate >= startDate && testDate <= endDate; }
Not sure if it's relevant, but the dates I'm pulling from the database have timestamps.
The after() method is used to check if a given date is after another given date. Return Value: true if and only if the instant represented by this Date object is strictly later than the instant represented by when; false otherwise.
allMatch(date::isBefore); boolean afterLatest = ! beforeEarliest && Stream. of(date1, date2, date3). allMatch(date::isAfter);
Core Java The class Date represents a specific instant in time, with millisecond precision. To find out if two Date objects contain the same day, we need to check if the Year-Month-Day is the same for both objects and discard the time aspect.
boolean isWithinRange(Date testDate) { return !(testDate.before(startDate) || testDate.after(endDate)); }
Doesn't seem that awkward to me. Note that I wrote it that way instead of
return testDate.after(startDate) && testDate.before(endDate);
so it would work even if testDate was exactly equal to one of the end cases.
ZoneId z = ZoneId.of( "America/Montreal" ); // A date only has meaning within a specific time zone. At any given moment, the date varies around the globe by zone. LocalDate ld = givenJavaUtilDate.toInstant() // Convert from legacy class `Date` to modern class `Instant` using new methods added to old classes. .atZone( z ) // Adjust into the time zone in order to determine date. .toLocalDate(); // Extract date-only value. LocalDate today = LocalDate.now( z ); // Get today’s date for specific time zone. LocalDate kwanzaaStart = today.withMonth( Month.DECEMBER ).withDayOfMonth( 26 ); // Kwanzaa starts on Boxing Day, day after Christmas. LocalDate kwanzaaStop = kwanzaaStart.plusWeeks( 1 ); // Kwanzaa lasts one week. Boolean isDateInKwanzaaThisYear = ( ( ! today.isBefore( kwanzaaStart ) ) // Short way to say "is equal to or is after". && today.isBefore( kwanzaaStop ) // Half-Open span of time, beginning inclusive, ending is *exclusive*. )
Date-time work commonly employs the "Half-Open" approach to defining a span of time. The beginning is inclusive while the ending is exclusive. So a week starting on a Monday runs up to, but does not include, the following Monday.
Java 8 and later comes with the java.time
framework built-in. Supplants the old troublesome classes including java.util.Date/.Calendar
and SimpleDateFormat
. Inspired by the successful Joda-Time library. Defined by JSR 310. Extended by the ThreeTen-Extra project.
An Instant
is a moment on the timeline in UTC with nanosecond resolution.
Instant
Convert your java.util.Date
objects to Instant objects.
Instant start = myJUDateStart.toInstant(); Instant stop = …
If getting java.sql.Timestamp
objects through JDBC from a database, convert to java.time.Instant in a similar way. A java.sql.Timestamp
is already in UTC so no need to worry about time zones.
Instant start = mySqlTimestamp.toInstant() ; Instant stop = …
Get the current moment for comparison.
Instant now = Instant.now();
Compare using the methods isBefore, isAfter, and equals.
Boolean containsNow = ( ! now.isBefore( start ) ) && ( now.isBefore( stop ) ) ;
LocalDate
Perhaps you want to work with only the date, not the time-of-day.
The LocalDate
class represents a date-only value, without time-of-day and without time zone.
LocalDate start = LocalDate.of( 2016 , 1 , 1 ) ; LocalDate stop = LocalDate.of( 2016 , 1 , 23 ) ;
To get the current date, specify a time zone. At any given moment, today’s date varies by time zone. For example, a new day dawns earlier in Paris than in Montréal.
LocalDate today = LocalDate.now( ZoneId.of( "America/Montreal" ) );
We can use the isEqual
, isBefore
, and isAfter
methods to compare. In date-time work we commonly use the Half-Open approach where the beginning of a span of time is inclusive while the ending is exclusive.
Boolean containsToday = ( ! today.isBefore( start ) ) && ( today.isBefore( stop ) ) ;
Interval
If you chose to add the ThreeTen-Extra library to your project, you could use the Interval
class to define a span of time. That class offers methods to test if the interval contains, abuts, encloses, or overlaps other date-times/intervals.
The Interval
class works on Instant
objects. The Instant
class represents a moment on the timeline in UTC with a resolution of nanoseconds (up to nine (9) digits of a decimal fraction).
We can adjust the LocalDate
into a specific moment, the first moment of the day, by specifying a time zone to get a ZonedDateTime
. From there we can get back to UTC by extracting a Instant
.
ZoneId z = ZoneId.of( "America/Montreal" ); Interval interval = Interval.of( start.atStartOfDay( z ).toInstant() , stop.atStartOfDay( z ).toInstant() ); Instant now = Instant.now(); Boolean containsNow = interval.contains( now );
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.
Where to obtain the java.time
classes?
java.time
functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With