Die Period
-Klasse in java.time behandelt nur den datumsorientierten Trank: Jahre, Monate, Tage.
Was ist mit dem Zeitabschnitt: Stunden, Minuten, Sekunden?
Wie können wir String-Repräsentationen vollständiger Perioden parsen und generieren, wie in ISO 8601 definiert, PnYnMnDTnHnMnS
? Zum Beispiel eineinhalb Tage: P1DT12H
. Das akademische Jahr ist neun Monate, P9M
. Jedes Jahr bekomme ich zwei Wochen und drei Tage Urlaub, P17D
. Der Kunde bewohnte das Hotelzimmer für 2 Tage und siebzehneinhalb Stunden, P2DT17H30M
.
Die Period
Klasse in Joda-Time behandelt vollen Zeitraum. Warum nicht in java.time? Gibt es einen anderen Mechanismus?
org.threeten.extra.PeriodDuration
Das ThreeTen-Extra Projekt bietet eine Klasse, die ein Period
und ein %Code%. Einfach Duration
genannt.
Zeit im ISO-8601-Kalendersystem, die einen Punkt und eine Dauer kombiniert.
Diese Klasse modelliert eine Menge oder einen Zeitraum in Form eines Zeitraums und einer Dauer. Ein Zeitraum ist ein datumsbasierter Zeitraum, bestehend aus Jahren, Monaten und Tagen. Eine Dauer ist eine zeitbasierte Zeitspanne, die aus Sekunden und Nanosekunden besteht. Weitere Informationen finden Sie in den Klassen "Periode" und "Dauer".
Die Tage in einem Zeitraum berücksichtigen Änderungen der Sommerzeit (23 oder 25 Stunden). Bei Berechnungen wird zuerst die Periode und dann die Dauer hinzugefügt.
Vorbehalt: Lesen Sie unbedingt die Antwort von JodaStephen , um die Probleme zu verstehen, die beim Kombinieren von PeriodDuration
und Period
.
In Java SE 8 liegt es in der Verantwortung der Anwendung, eine Klasse zu erstellen, die Period
und Duration
verbindet, falls dies erforderlich ist.
Beachten Sie, dass ein Duration
eine Anzahl von Sekunden enthält, nicht getrennte Mengen von Sekunden, Minuten und Stunden. Die Anzahl der Sekunden kann 24 Stunden überschreiten, daher kann Duration
einen "Tag" darstellen. Aber es ist ein fester 24-Stunden-Tag. Im Gegensatz dazu ist die Darstellung eines "Tages in Period
deskriptiv und berücksichtigt DST. Der Zustand eines Period
besteht aus drei getrennten Feldern - Tagen, Monaten und Jahren.
Bedenken Sie, dass "der Kunde das Hotelzimmer für 2 Tage und 17 1/2 Stunden besetzt hat, P2DT17H30M" die Möglichkeit hat, sich durch DST-Umstellungen zu verkomplizieren. Mit Period
und Duration
separat sind die Dinge klar - Period
ist von DST-Anpassungen betroffen und Duration
nicht.
In Designbegriffen enthielt das ursprüngliche java.time Period
Stunden, Minuten und Sekunden. Dies führte jedoch dazu, dass viele Methoden und komplizierte Javadoc benötigt wurden, um alle Möglichkeiten rund um Normalisierung und DST zu beschreiben. Durch die Trennung der Konzepte wird die Interaktion mit der Zeitachse deutlich klarer. Beachten Sie, dass sich die beiden Klassen auch auf das SQL-Design beziehen (Konzepte "Jahr zu Monat" und "Tag zu Sekunde").
Es gibt derzeit keine Pläne, eine neue Klasse für Java SE 9 in diesem Bereich hinzuzufügen, dies kann jedoch nicht vollständig ausgeschlossen werden, da XML / ISO-8601 eine einzelne kombinierte Darstellung zulässt.
Kurze Antwort bezogen auf java.time
(JSR-310):
Nein, dieses Paket bietet keine Lösung.
Alternativ können Sie die Klasse Dauer im Paket javax.xml.datatype
zum Analysieren von Strings wie PnYnMnDTnHnMnS
. Dies ist auch in älteren JDK-Versionen seit Java-5 verfügbar. Beispiel:
Wenn Sie nach Einschränkungen / Problemen fragen, nun, hier bekommen Sie eine Liste:
Einige (alternative) ISO-Formate wie P0001-04-20T4H
können nicht analysiert werden.
Einige in javax.xml.datatype.Duration
definierte Methoden beruhen auf einer internen Calendar
-instance (dokumentiert), sodass diese Methoden möglicherweise nicht funktionieren, wenn eine Instanz von Duration
sehr große Werte enthält.
Die Arbeit mit Sekundenbruchteilen ist möglicherweise umständlich und manchmal in der Genauigkeit eingeschränkt, wenn Sie mit Calendar
-instance arbeiten.
Es gibt nur eine einzige Normalisierungsmethode, die Calendar
-instance verwendet. Zumindest diese Methode berücksichtigt die DST-Effekte standardmäßig.
Formatierung (nicht einmal lokales Drucken zu erwähnen) wird nicht angeboten.
Wenn Sie diese Probleme überwinden wollen, dann können Sie eine externe Bibliothek in Erwägung ziehen (und ja, ich denke nicht nur an Joda-Time, deren Genauigkeit auf Millisekunden beschränkt ist und deren Internationalisierung ebenfalls begrenzt ist). Andernfalls hat das Paket javax.xml.datatype
den Vorteil, den Aufwand zum Einbetten einer externen Bibliothek in den Klassenpfad zu sparen.
Aktualisierung:
Über die Frage im Kommentar zu externen Bibliotheken kenne ich Joda-Time und meine Bibliothek Time4J.
Der erste ( Joda-Time ) bietet eine spezielle Klasse namens ISOPeriodFormat . Diese Klasse ist auch in der Lage, alternative ISO-Formate zu analysieren (obwohl PyyyyWwwddThhmmss nicht im Original ISO-8601-Papier erwähnt wird, während die Unterstützung für PYYYY-DDD fehlt). Joda-Time definiert einen Builder-gesteuerten Ansatz für Periodenformatierer, der auch für das Drucken von Zeiträumen (Perioden) verwendet werden kann. Darüber hinaus gibt es eine begrenzte Unterstützung für lokales Drucken (mit Version 2.9.3 von Joda-Time in 13 Sprachen). Schließlich bietet die Klasse Period
verschiedene Normalisierungsmethoden (siehe javadoc ).
Die zweite ( Time4J ) bietet die Klassen net.time4j.Duration und zwei Formatierungswerkzeuge ( Duration.Formatter für pattern-basiertes Drucken / Parsen und net.time4j .PrettyTime für lokales Drucken in tatsächlich 78 Sprachen). Die Klasse Duration
bietet zum Parsen von ISO-Strings die statische Methode parsePeriod (String) und verschiedene Normalisierungsmethoden. Beispiel für die Interoperabilität mit java.time
(JSR-310) beweist, dass diese Bibliothek als mächtige Erweiterung des neuen java-8-date-time-api betrachtet und verwendet werden kann:
Der Vollständigkeit halber sollte ich auch ocpsoft.PrettyTime erwähnen, aber ich bin nicht sicher, ob diese Bibliothek ISO-Strings verarbeiten kann . Es ist eher für relative Zeiten ausgelegt.