Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java 8: Calculate difference between two ZonedDateTime

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.

like image 204
Maggie Hill Avatar asked Dec 10 '16 15:12

Maggie Hill


People also ask

How do you subtract ZonedDateTime?

minus() method of a ZonedDateTime class used to returns a copy of this date-time with the specified amount subtracted to date-time. The amount is typically Period or Duration but may be any other type implementing the TemporalAmount interface.

What is the difference between two LocalDateTime in Java 8?

getDays() + " days " + time[0] + " hours " + time[1] + " minutes " + time[2] + " seconds.");

How do you calculate the difference between two dates in Java?

getTime() – d1. getTime(). Use date-time mathematical formula to find the difference between two dates. It returns the years, days, hours, minutes, and seconds between the two specifies dates.

How can you tell the difference between two Localates?

In Java 8, we can use Period , Duration or ChronoUnit to calculate the difference between two LocalDate or LocaldateTime . Period to calculate the difference between two LocalDate .


2 Answers

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.

like image 80
Michał Szewczyk Avatar answered Sep 21 '22 05:09

Michał Szewczyk


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?

  • Java SE 8, Java SE 9, Java SE 10, 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 Java SE 7
    • Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
  • Android
    • Later versions of Android bundle implementations of the java.time classes.
    • For earlier Android (<26), the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….

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.

like image 43
Basil Bourque Avatar answered Sep 21 '22 05:09

Basil Bourque