tl;dr
11:00 PM to 7:30 AM = 7.5 or 8.0 or 8.5 or 9.5 or some other number of hours depending on the particular dates and time zone.
Duration.between(
ZonedDateTime.of( 2019 , 1 , 23 , 23 , 0 , 0 , 0 , ZoneId.of( "Africa/Cairo" ) ) ,
ZonedDateTime.of( 2019 , 1 , 24 , 7 , 30 , 0 , 0 , ZoneId.of( "Africa/Cairo" ) )
)
.toString()
See this code run live at IdeOne.com.
PT8H30M
Calculating elapsed time requires date, time-of-day, and time zone
The Answer by Markus Hänsel is headed the right way, but fails to account for anomalies such as Daylight Saving Time (DST).
Your Question is not quite clear. Do you mean to track the general idea of time-of-day using generic 24-hour days? Or do you mean to track actual moments, such as the time slept two days ago, the time slept yesterday, and so on?
If the latter, then you cannot use LocalDateDate
as that class cannot, by definition, track moments. The LocalDateTime
class lacks any concept of time zone or offset-from-UTC. As such, a LocalDateTime
represents potential moments along a range of about 26-27 hours (the range of time zones around the globe).
Given your example of 11:00 pm to 7:30 am, that would mean 8.5 hours in a certain time zone with no anomalies on that date. But on a day of DST cut-over that might mean 7.5 hours (“Spring ahead”), or 9.5 hours (“Fall back”). Or maybe 8.0 hours on day such as last year when North Korea adjusted their clock by a half-hour. Or when in 2007 Venezuela turned back time a half-hour… and then a decade later flipped back again. These changes happen more often than you may realize. Politicians around the globe have shown a penchant for redefining the offset of their time zone(s).
➥ The upshot is that you cannot reliably calculate elapsed time with only the time-of-day. You must use a date and a time zone.
ZoneId
Specify a proper time zone name in the format of Continent/Region
, such as America/Montreal
, Africa/Casablanca
, or Pacific/Auckland
. Never use the 2-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( "Africa/Tunis" ) ;
ZonedDateTime
To track moments, use the ZonedDateTime
class. This class combines a date, a time-of-day, and a time zone.
LocalDate ldStart = LocalDate.of( 2019 , 1 , 23 ) ;
LocalTime ldStart = LocalTime.of( 23 , 0 ) ;
ZonedDateTime zdtStart = ZonedDateTime.of( ldStart , ltStart , z ) ;
And the stop time.
LocalDate ldStop = LocalDate.of( 2019 , 1 , 24 ) ; // Next day.
LocalTime ldStop = LocalTime.of( 7 , 30 ) ;
ZonedDateTime zdtStop = ZonedDateTime.of( ldStop , ltStop , z ) ;
Calculate elapsed time using Duration
class.
Duration d = Duration.between( zdtStart , zdtStop ) ;
ISO 8601
I recommend you not report elapsed time using time-of-day format, HH:MM:SS. Instead use the standard format defined for this purpose, in the ISO 8601 standard.
So, 8.5 hours would be PT8H30M
.
The java.time classes use ISO 8601 formats by default when parsing/generating strings.
String output = d.toString() ; // Generate `PT8H30M`.
And parsing.
Duration d = Duration.parse( "PT8H30M" ) ;
About java.time
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.