tl;dr
For time-of-day only, without a date or time zone.
LocalTime start = LocalTime.of( "16:40" ) ;
LocalTime stop = LocalTime.of( "17:00" ) ;
Duration d = Duration.between( start , stop ) ;
PT20M
Or, for date-time in a zone.
ZoneId z = ZoneId.of( "America/Montreal" )
ZonedDateTime zdtNow = ZonedDateTime.now( z );
ZonedDateTime zdtThen =
ZonedDateTime.of( // Pass a LocalDate, LocalTime, ZoneId.
zdtNow.toLocalDate() , // Same date…
LocalTime.parse( "16:30:00" ) , // … but different time-of-day.
z
)
Duration d = Duration.between( zdtNow , zdtThen ) ;
PT2H30M
Details
You are using old date-time classes, now legacy, supplanted by the java.time classes.
LocalTime
You are incorrectly using a date-time class for a time-of-day-only value. Instead use the LocalTime
class. And use a span-of-time class when calculating elapsed time.
String input = "16:30:00" ;
LocalTime lt = LocalTime.parse( input );
Instant
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).
Instant instant = Instant.now();
ZonedDateTime
Determining a wall-clock time requires a time zone. Specify a proper time zone name in the format of continent/region
, such as America/Montreal
, Africa/Casablanca
, or Pacific/Auckland
. Never use the 3-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( "America/Montreal" );
ZonedDateTime zdtNow = instant.atZone( z ); // Adjusted into your time zone.
Now construct a ZonedDateTime
for your given input time-of-day.
ZonedDateTime zdtTarget = ZonedDateTime.of( zdtNow.toLocalDate() , lt , z );
Duration
Use Duration
to represent elapsed time not attached to the timeline.
Duration d = Duration.between( zdtNow , zdtTarget );
Note that the duration will be a negative amount if the specified time-of-day is earlier than the current time-of-day.
ISO 8601 string for duration
To get a String describing the hours, minutes, etc. of that span of time, simply call toString
to generate a String in standard ISO 8601 format of PnYnMnDTnHnMnS
where P
marks the beginning and T
separates the years-month-days from hours-minutes-seconds.
If the current time were 14:00:00
in the same zone, the output would be:
PT2H30M
Getter methods
Oddly, in Java 8 this class Duration
lacks any getter methods for the parts such as 2
for hours and 30
for minutes. Remedied in Java 9 with methods such as toHoursPart
and toMinutesPart
.
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 java.time.
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 SE 8 and SE 9 and later
- Built-in.
- Part of the standard Java API with a bundled implementation.
- Java 9 adds some minor features and fixes.
- Java SE 6 and SE 7
- Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
- Android
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.