Time marches on
Be careful about passing around enum values for “yesterday”, “tomorrow”, and so on. That raises a couple of issues, time zone and midnight.
Dates and day-of-week only have meaning in the context of a time zone. For any given moment, the date varies around the globe. For example, a few minutes after midnight in Paris is still “yesterday” in Montréal. So when ever you intend “yesterday” and such, always specify the desired/expected time zone as well.
Each non-atomic command and line of code executes separately from the previous. Each execution takes a moment of time, however brief. At any of those moments midnight in the specified time zone may be rolling over into a new day. At that stroke of midnight, your relative-time flag such as “yesterday” suddenly takes on a whole new meaning. That meaning is likely different that was intended by the earlier code given that conditions (the date) were different when that code began.
So it makes more sense to me to be passing around Instant
objects, or perhaps OffsetDateTime
or ZonedDateTime
objects. These date-time values are frozen, representing a specific moment on the timeline. Your earlier original code can verify the meaning of that value, check that the date is indeed a Friday
or some such. After such verification, the value can be passed on to other code. Now you need not worry about strange occasional bugs occurring at midnight.
java.time
You don't really need to build a class or enum to express your intention of relative time such as “yesterday”. The java.time classes built into Java 8 and later have plain-reading methods for adding and subtracting days, weeks, months. These are basically one-liners, so just call these plus…
and minus…
methods directly.
ZonedDateTime now = ZonedDateTime.now();
ZonedDateTime yesterday = now.minusDays( 1 );
ZonedDateTime weekLater = now.plusWeeks( 1 );
That code is implicitly applying the JVM’s current default time zone. Better to specify.
ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime now = ZonedDateTime.now( zoneId );
You may want the date-only without time-of-day and without time zone. Use LocalDate
.
LocalDate weekPrior = now.toLocalDate().minusWeeks( 1 );
You may want to get first moment of the day. Not always the time of 00:00:00.0
.
ZonedDateTime yesterdayStart = now.minusDays( 1 ).toLocalDate().atStartOfDay( zoneId );
If you want to represent the span of time defined by a pair of date-time values, look at the Interval
class found in the ThreeTen-Extra project that extends the java.time framework. This class tracks a pair of Instant
objects which are moments on the timeline in UTC. You can extract an Instant
from your ZonedDateTime
by calling toInstant
.
Interval intervalYesterday = Interval.of( yesterdayStart.toInstant() , yesterdayStart.plusDays( 1 ).toInstant() );
To get from an Instant
back to a zoned date-time, apply a ZoneId
.
ZonedDateTime zdt = ZonedDateTime( instant , zoneId );
For a date-only interval, you'll need to build your own class that stores a pair of LocalDate
objects. I would call it something like DateRange
.
Tip: Search "Half-Open" to learn about the practice of tracking spans of time where beginning in inclusive while the ending is exclusive.