Java 8: Calculate difference between two ZonedDateTime

64,420

Solution 1

You can use method between from ChronoUnit.

This method converts those times to same zone (zone from the first argument) and after that, invokes until method declared in Temporal interface:

static long zonedDateTimeDifference(ZonedDateTime d1, ZonedDateTime d2, ChronoUnit unit){
    return unit.between(d1, d2);
}

Since both ZonedDateTime and LocalDateTime implements Temporal interface, you can write also universal method for those date-time types:

static long dateTimeDifference(Temporal d1, Temporal d2, ChronoUnit unit){
    return unit.between(d1, d2);
}

But keep in mind, that invoking this method for mixed LocalDateTime and ZonedDateTime leads to DateTimeException.

Hope it helps.

Solution 2

tl;dr

For hours, minutes, seconds:

Duration.between( zdtA , zdtB )  // Represent a span-of-time in terms of days (24-hour chunks of time, not calendar days), hours, minutes, seconds. Internally, a count of whole seconds plus a fractional second (nanoseconds).

For years, months, days:

Period.between(                  // Represent a span-of-time in terms of years-months-days. 
    zdtA.toLocalDate() ,         // Extract the date-only from the date-time-zone object. 
    zdtB.toLocalDate() 
)

Details

The Answer by Michal S is correct, showing ChronoUnit.

Duration & Period

Another route is the Duration and Period classes. Use the first for shorter spans of time (hours, minutes, seconds), the second for longer (years, months, days).

Duration d = Duration.between( zdtA , zdtB );

Produce a String in standard ISO 8601 format by calling toString. The format is PnYnMnDTnHnMnS where the P marks the beginning and T separates the two portions.

String output = d.toString();

In Java 9 and later, call the to…Part methods to get the individual components. Discussed in another Answer of mine.

Example code

ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdtStart = ZonedDateTime.now( z );
ZonedDateTime zdtStop = zdtStart.plusHours( 3 ).plusMinutes( 7 );

Duration d = Duration.between( zdtStart , zdtStop );

2016-12-11T03:07:50.639-05:00[America/Montreal]/2016-12-11T06:14:50.639-05:00[America/Montreal]

PT3H7M

See live code in IdeOne.com.

Interval & LocalDateRange

The ThreeTen-Extra project adds functionality to the java.time classes. One of its handy classes is Interval to represent a span of time as a pair of points on the timeline. Another is LocalDateRange, for a pair of LocalDate objects. In contrast, the Period & Duration classes each represent a span of time as not attached to the timeline.

The factory method for Interval takes a pair of Instant objects.

Interval interval = Interval.of( zdtStart.toInstant() , zdtStop.toInstant() );

You can obtain a Duration from an Interval.

Duration d = interval.toDuration();

Table of span-of-time classes in Java and in the ThreeTen-Extra project


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.

Solution 3

This gives you minutes between two ZonedDateTimes.

int minutes = (int) (end.toEpochSecond() - start.toEpochSecond()) / 60;
Share:
64,420
Maggie Hill
Author by

Maggie Hill

Updated on August 01, 2021

Comments

  • Maggie Hill
    Maggie Hill almost 3 years

    I'm trying to write a method to print the time difference between two ZonedDateTimes, regarding the difference between time zones.

    I found some solutions but all of them were written to work with LocalDateTime.