Java 8: Differenz zwischen zwei ZonedDateTime berechnen

Lesezeit: 3 Minuten

Benutzer-Avatar
Maggie Hill

Ich versuche, eine Methode zu schreiben, um den Zeitunterschied zwischen zwei zu drucken ZoneDateTimes, in Bezug auf den Unterschied zwischen Zeitzonen.

Ich habe einige Lösungen gefunden, aber alle wurden geschrieben, um damit zu arbeiten LocalDateTime.

  • Veröffentlichen Sie ein konkretes Beispiel dafür, was Sie erreichen möchten, und erhalten Sie ein Ergebnis.

    – JB Nizet

    10. Dezember 2016 um 15:31 Uhr

  • Michałs Antwort ist genau das, was ich erwartet hatte. Danke vielmals!

    – Maggie Hill

    10. Dezember 2016 um 15:58 Uhr

Benutzer-Avatar
Michal Szewczyk

Sie können Methode verwenden zwischen aus ChronoUnit.

Diese Methode konvertiert diese Zeiten in dieselbe Zone (Zone aus dem ersten Argument) und ruft danach auf bis um Methode deklariert in Zeitlich Schnittstelle:

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

Da beide ZoneDateTime und LocalDateTime implementiert Zeitlich Schnittstelle können Sie auch eine universelle Methode für diese Datums- und Uhrzeittypen schreiben:

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

Aber denken Sie daran, dass das Aufrufen dieser Methode für Mixed LocalDateTime und ZoneDateTime führt zu DateTimeException.

Ich hoffe es hilft.

  • Gibt es eine Möglichkeit, den Unterschied zwischen zwei ZDT-Typen zu ermitteln, bei denen die ZoneId zwischen den beiden ZDTs unterschiedlich ist?

    – Stanlick

    5. Januar 2018 um 23:13 Uhr

  • @stanlick Ja: Duration.between( zdtA , zdtB ) wie in meiner Antwort gezeigt. Ich stelle mir das vor between Methode ruft einfach auf ZonedDateTime::toInstant() auf beiden.

    – Basilikum Bourque

    27. Oktober 2019 um 3:18 Uhr


Benutzer-Avatar
Basil Bourque

tl;dr

Für Stunden, Minuten, Sekunden:

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).

Seit Jahren, Monaten, Tagen:

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() 
)

Einzelheiten

Die Antwort von Michal S ist korrekt und zeigt ChronoUnit.

Duration & Period

Eine andere Route ist die Duration und Period Klassen. Verwenden Sie die erste für kürzere Zeitspannen (Stunden, Minuten, Sekunden), die zweite für längere (Jahre, Monate, Tage).

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

Erzeuge einen String in Standardformat ISO 8601 durch Anruf toString. Das Format ist PnYnMnDTnHnMnS bei dem die P markiert den Anfang und T trennt die beiden Teile.

String output = d.toString();

Rufen Sie in Java 9 und höher die to…Part Methoden, um die einzelnen Komponenten zu erhalten. In einer anderen Antwort von mir besprochen.

Beispielcode

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

Sehen Live-Code in IdeOne.com.

Interval & LocalDateRange

Das ThreeTen-Extra project fügt den java.time-Klassen Funktionalität hinzu. Eine seiner praktischen Klassen ist Interval um eine Zeitspanne als Punktpaar auf der Zeitachse darzustellen. Ein anderer ist LocalDateRangefür ein Paar LocalDate Objekte. Im Gegensatz dazu die Period & Duration Klassen repräsentieren jeweils eine Zeitspanne als nicht an die Zeitleiste angehängt.

Die Fabrikmethode für Interval nimmt ein paar Instant Objekte.

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

Sie erhalten eine Duration von einem Interval.

Duration d = interval.toDuration();

Tabelle der Zeitspannenklassen in Java und im ThreeTen-Extra-Projekt


Um java.time

Das java.time Framework ist in Java 8 und höher integriert. Diese Klassen ersetzen die lästigen alten Erbe Datum-Zeit-Klassen wie z java.util.Date, Calendar& SimpleDateFormat.

Das Joda-Zeit Projekt, jetzt in Wartungsmodusrät zur Migration in die java.time Klassen.

Weitere Informationen finden Sie unter Oracle-Tutorial. Und durchsuchen Sie Stack Overflow nach vielen Beispielen und Erklärungen. Spezifikation ist JSR310.

Sie dürfen umtauschen java.time Objekte direkt mit Ihrer Datenbank. Verwenden ein JDBC-Treiber gemäß JDBC 4.2 oder später. Keine Notwendigkeit für Saiten, keine Notwendigkeit für java.sql.* Klassen.

Wo erhalte ich die java.time-Klassen?

  • Java SE 8, Java SE 9, JavaSE 10und später
    • Eingebaut.
    • Teil der Standard-Java-API mit einer gebündelten Implementierung.
    • Java 9 fügt einige kleinere Funktionen und Korrekturen hinzu.
  • Java SE 6 und Java SE 7
    • Ein Großteil der java.time-Funktionalität wurde in Java 6 & 7 zurückportiert ThreeTen-Backport.
  • Android
    • Spätere Versionen von Android-Bundle-Implementierungen der java.time Klassen.
    • Für frühere Android-Versionen (<26) ist die ThreeTenABP Projekt passt ThreeTen-Backport (oben erwähnt). Sehen Wie benutzt man ThreeTenABP….

Das ThreeTen-Extra project erweitert java.time um zusätzliche Klassen. Dieses Projekt ist ein Testfeld für mögliche zukünftige Ergänzungen zu java.time. Sie können hier einige nützliche Klassen finden, wie z Interval, YearWeek, YearQuarterund mehr.

  • Wo siehst du ein of Methode auf Dauer, die zwei Augenblicke dauert? Ich sehe nur public static Duration of(long amount, TemporalUnit unit)

    – Lappen

    27. September 2017 um 0:02 Uhr

  • @BrianGordon Behoben, ersetzt .of mit .between. Vielen Dank.

    – Basilikum Bourque

    27. September 2017 um 0:14 Uhr


  • Duration funktioniert mit ZonedDateTime, während Period mit LocalDate funktioniert. ein Aufruf der Methode toLocalDate() muss für unser zdt-Objekt erfolgen.

    – Guillaume Guerin

    2. März 2018 um 16:50 Uhr


  • @guillaumeguerin Du hast Recht. Mein Codebeispiel wurde korrigiert. Vielen Dank.

    – Basilikum Bourque

    2. März 2018 um 17:14 Uhr

  • Oh Mann, vielen Dank, Ihr Beispiel ist ziemlich gut !!!!

    – Brendon Iwata

    23. Juni 2020 um 13:59 Uhr

Benutzer-Avatar
Alvin Avanessian

Dadurch erhalten Sie Minuten zwischen zwei ZonedDateTimes.

int minutes = (int) (end.toEpochSecond() - start.toEpochSecond()) / 60;

  • Vielen Dank, dass Sie einen Beitrag leisten möchten. Tut mir leid, das ist nicht der empfohlene Weg, und in besonderen Fällen liefert er völlig falsche Ergebnisse.

    – Ole VV

    31. Juli 2021 um 19:26 Uhr

1299000cookie-checkJava 8: Differenz zwischen zwei ZonedDateTime berechnen

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy