An instant is a moment on the timeline. It depends whether you want to take timezones and DST changes into consideration or not.
If you don't care about timezone or DST, you could do
LocalDateTime now = LocalDateTime.now();
ChronoUnit.HOURS.between(now.toLocalDate().atStartOfDay(), now);
The returned long
is the number of hours between midnight and the current time. This will be by far in most cases the hour number as displayed by your wall clock. Also note that this code snippet does not make use of Instant
, since and instant does not know about the human representation of time, like 00:00:00 midnight.
If you do care about timezone or DST, then you need to specify your timezone in order to adjust for time changes. For instance, within Europe/Amsterdam
timezone, on March 29, 2020 at 02:00 wall clock time, the clock skips 1 hour because of DST (called "zomertijd" or "summer time"), so if now
is 14:39 wall clock time, the number of hours since midnight is not 14 but 13.
You can then do something like this:
ZoneId zone = ...
Instant now = Instant.now();
Instant midnight = now.atZone(zone).toLocalDate().atStartOfDay(zone).toInstant();
long result = ChronoUnit.MINUTES.between(midnight, now);
Make sure you query now()
once, otherwise you may get wrong results in corner cases.