The AtStartOfDay value of a AtStartOfDay object has the magic you are looking for.
A few points:
Itβs better to get used to separating the clock instance from the Now call. This makes it easier to replace the watch later when testing devices.
You only need to get the local time zone once. I prefer to use the Tzdb provider, but any provider will work for this purpose.
At the end of the day, it is better to use the beginning of the next day. This prevents you from dealing with detailing issues, for example, whether you should take 23:59, 23:59:59, 23: 59.999, 23: 59: 59.9999999, etc. In addition, it is simplified to obtain an integer number of results when performing math.
In general, date + time ranges (or time-only ranges) should be considered as half-open intervals [start,end) - while dates-only ranges should be considered as completely closed [start,end] intervals.
Because of this, the beginning is compared with <= , but the end is compared with > .
If you know for sure that a different ZonedDateTime value is in the same time zone and uses the same calendar, you can omit calls to ToInstant and simply compare them directly.
Update
As John mentioned in the comments, the Interval type may be useful for this purpose. It is already configured to work with a semi-open range of Instant values. The following function will receive the interval for the current "day" in a specific time zone:
public Interval GetTodaysInterval(IClock clock, DateTimeZone timeZone) { LocalDate today = clock.Now.InZone(timeZone).Date; ZonedDateTime dayStart = timeZone.AtStartOfDay(today); ZonedDateTime dayEnd = timeZone.AtStartOfDay(today.PlusDays(1)); return new Interval(dayStart.ToInstant(), dayEnd.ToInstant()); }
Name it like this (using the same values ββabove):
Interval day = GetTodaysInterval(systemClock, tz);
And now the comparison can be done using the Contains function:
bool between = day.Contains(other.ToInstant());
Note that you still need to convert to Instant , since the Interval type is not a time zone.
source share