Unterschiede zwischen Java 8 Date Time API (java.time) und Joda-Time

264

Ich weiß, dass es Fragen zu java.util.Date und Joda-Time gibt. Nach einigem Graben konnte ich jedoch keinen Thread über die Unterschiede zwischen der java.time-API (neu in Java 8 , definiert durch JSR 310 ) und Joda-Time finden .

Ich habe gehört, dass die java.time-API von Java 8 viel sauberer ist und viel mehr kann als Joda-Time. Aber ich kann keine Beispiele finden, die die beiden vergleichen.

  • Was kann java.time tun, was Joda-Time nicht kann?
  • Was kann java.time besser als Joda-Time?
  • Ist die Leistung mit java.time besser?
Zack
quelle
8
Es ist nicht so, dass es sich um Java 7 handelt, nicht um Java 8. Die Antwort auf diese Frage wurde für Java 8 mit sehr sehr geringen Details bearbeitet. Meine Frage bezieht sich speziell auf die neue DateTime-API von Java 8, nicht auf java.util.Date von Java 7. Ich suche nur nach einer Antwort, die Java 8 mit JodaTime vergleicht.
Zack
2
Vielleicht kann Ihnen dieses Oracle-Dokument helfen.
MarioDS
Wenn Sie Java 7 haben, verwenden Sie die zusätzliche Bibliothek. Wenn Sie Java 8 haben, verwenden Sie die integrierte Bibliothek. Da beide Bibliotheken im Grunde genommen von derselben Person entworfen wurden, bin ich mir nicht sicher, welche wesentlichen Unterschiede Sie erwarten.
Peter Lawrey
2
@ PeterLawrey: Joda-Time und die Java 8-API für Datum und Uhrzeit sind tatsächlich sehr unterschiedlich.
jarnbjo
5
Sie können auch diesen Blog-Beitrag von Stephen Colbourne lesen - dem Hauptautor beider Projekte.
Matt Johnson-Pint

Antworten:

416

Gemeinsamkeiten

a) Beide Bibliotheken verwenden unveränderliche Typen. Joda-Time bietet auch zusätzliche veränderbare Typen wie MutableDateTime.

b) Außerdem: Beide Bibliotheken sind inspiriert von der Designstudie "TimeAndMoney" von Eric Evans oder Ideen von Martin Fowler zum domänengetriebenen Stil, sodass sie mehr oder weniger nach einem fließenden Programmierstil streben (obwohl nicht immer perfekt ;-)).

c) Mit beiden Bibliotheken erhalten wir einen realen Kalenderdatumstyp (aufgerufen LocalDate), einen realen Wandzeittyp (aufgerufen LocalTime) und die Komposition (aufgerufen LocalDateTime). Das ist ein sehr großer Gewinn im Vergleich zu alt java.util.Calendarund java.util.Date.

d) Beide Bibliotheken verwenden einen methodenzentrierten Ansatz, dh sie ermutigen den Benutzer, getDayOfYear()stattdessen zu verwenden get(DAY_OF_YEAR). Dies führt zu vielen zusätzlichen Methoden im Vergleich zu java.util.Calendar(obwohl letztere aufgrund des übermäßigen Einsatzes von Ints überhaupt nicht typsicher sind).

Performance

Siehe die andere Antwort von @ OO7, die auf die Analyse von Mikhail Vorontsov verweist, obwohl Punkt 3 (Ausnahmefang) wahrscheinlich veraltet ist - siehe diesen JDK-Fehler . Die unterschiedliche Leistung (die im Allgemeinen für JSR-310 spricht) ist hauptsächlich auf die Tatsache zurückzuführen, dass bei der internen Implementierung von Joda-Time immer ein maschinenzeitähnliches Langprimitiv (in Millisekunden) verwendet wird.

Null

Joda-Time verwendet häufig NULL als Standard für die Systemzeitzone, das Standardgebietsschema, den aktuellen Zeitstempel usw., während JSR-310 fast immer NULL-Werte ablehnt.

Präzision

JSR-310 verarbeitet Nanosekundengenauigkeit, während Joda-Time auf Millisekundengenauigkeit beschränkt ist .

Unterstützte Felder:

Eine Übersicht über unterstützte Felder in Java-8 (JSR-310) geben einige Klassen im temporalen Paket (z. B. ChronoField und WeekFields ), während Joda-Time in diesem Bereich eher schwach ist - siehe DateTimeFieldType . Der größte Mangel an Joda-Zeit ist hier das Fehlen lokalisierter wochenbezogener Felder. Ein gemeinsames Merkmal beider Feldimplementierungsdesigns ist, dass beide auf Werten vom Typ long basieren (keine anderen Typen, nicht einmal Aufzählungen).

Aufzählung

JSR-310 bietet Aufzählungen wie DayOfWeekoder, Monthwährend Joda-Time dies nicht anbietet, da es hauptsächlich in den Jahren 2002-2004 vor Java 5 entwickelt wurde .

Zonen-API

a) JSR-310 bietet mehr Zeitzonenfunktionen als Joda-Time. In letzter Zeit kann kein programmatischer Zugriff auf die Historie der Zeitzonenversatzübergänge gewährt werden, während JSR-310 dies kann.

b) Zu Ihrer Information: JSR-310 hat sein internes Zeitzonen-Repository an einen neuen Speicherort und in ein anderes Format verschoben. Der alte Bibliotheksordner lib / zi existiert nicht mehr.

Einsteller gegen Eigentum

JSR-310 hat die TemporalAdjusterSchnittstelle als formalisierte Methode zur Externalisierung zeitlicher Berechnungen und Manipulationen eingeführt, insbesondere für Bibliotheks- oder Framework-Writer. Dies ist eine nette und relativ einfache Möglichkeit, neue Erweiterungen von JSR-310 einzubetten (eine Art Äquivalent zum statischen Helfer) Klassen für ehemalige java.util.Date).

Für die meisten Benutzer hat diese Funktion jedoch nur einen sehr begrenzten Wert, da die Last zum Schreiben von Code immer noch beim Benutzer liegt. TemporalAdjusterEs gibt nicht so viele integrierte Lösungen, die auf dem neuen Konzept basieren. Derzeit gibt es nur TemporalAdjustersdie Hilfsklasse mit einer begrenzten Anzahl von Manipulationen (und die Aufzählungen Monthoder andere zeitliche Typen).

Joda-Time bietet ein Feldpaket an, aber die Praxis hat gezeigt, dass neue Feldimplementierungen sehr schwer zu codieren sind. Auf der anderen Seite bietet Joda-Time sogenannte Eigenschaften, die einige Manipulationen viel einfacher und eleganter machen als in JSR-310, zum Beispiel property.withMaximumValue () .

Kalendersysteme

JSR-310 bietet 4 zusätzliche Kalendersysteme. Das interessanteste ist Umalqura (in Saudi-Arabien verwendet). Die anderen 3 sind: Minguo (Taiwan), Japanisch (nur der moderne Kalender seit 1871!) Und ThaiBuddhist (erst nach 1940 korrekt).

Joda-Time bietet einen islamischen Kalender auf der Basis von Berechnungen an - keinen auf Sichtungen basierenden Kalender wie Umalqura. Thai-Buddhist wird auch von Joda-Time in ähnlicher Form angeboten, Minguo und der Japaner nicht. Ansonsten bietet Joda-Time auch einen koptischen und einen äthiopischen Kalender an (jedoch ohne Unterstützung für die Internationalisierung).

Interessanter für Europäer: Joda-Time bietet auch einen gregorianischen , julianischen und gemischt-gregorianisch- julianischen Kalender an. Der praktische Wert für reale historische Berechnungen ist jedoch begrenzt, da wichtige Merkmale wie unterschiedliche Jahresbeginn in der Datumshistorie überhaupt nicht unterstützt werden (dieselbe Kritik gilt auch für alte java.util.GregorianCalendar).

Weitere Kalender wie Hebräisch oder Persisch oder Hindu in beiden Bibliotheken vollständig fehlen.

Epochentage

JSR-310 hat die Klasse JulianFields, während Joda-Time (Version 2.0) einige Hilfsmethoden in der Klasse DateTimeUtils anbietet .

Uhren

JSR-310 hat keine Schnittstelle (ein Entwurfsfehler), sondern eine abstrakte Klasse java.time.Clock, die für jede Taktabhängigkeitsinjektion verwendet werden kann. Joda-Time bietet stattdessen die Schnittstelle MillisProvider und einige Hilfsmethoden in DateTimeUtils . Auf diese Weise kann Joda-Time auch testgetriebene Modelle mit unterschiedlichen Uhren (Verspottung usw.) unterstützen.

Dauer Arithmetik

Beide Bibliotheken unterstützen die Berechnung von Zeitabständen in einer oder mehreren zeitlichen Einheiten. Beim Umgang mit Einzeleinheiten ist der JSR-310-Stil jedoch offensichtlich besser (und langbasiert, anstatt int zu verwenden):

JSR-310 => long days = ChronoUnit.DAYS.between(date1, date2);

Joda-Zeit => int days = DAYS.daysBetween(date1, date2).getDays();

Die Handhabung der Dauer mehrerer Einheiten ist ebenfalls unterschiedlich. Auch die Berechnungsergebnisse können abweichen - siehe dieses geschlossene Joda-Time-Problem . Während JSR-310 einen sehr einfachen und begrenzten Ansatz verwendet, um nur die Klassen Period(Dauer basierend auf Jahren, Monaten und Tagen) und Duration(basierend auf Sekunden und Nanosekunden) zu verwenden, verwendet Joda-Time eine ausgefeiltere Methode, um die Klasse PeriodTypezu steuern in welchen Einheiten eine Dauer (Joda-Time nennt es "Periode") ausgedrückt werden soll. WährendPeriodType-API ist irgendwie umständlich zu verwenden, eine ähnliche Methode wird von JSR-310 überhaupt nicht angeboten. Insbesondere ist es in JSR-310 noch nicht möglich, gemischte Datums- und Zeitdauern (z. B. basierend auf Tagen und Stunden) zu definieren. Seien Sie also gewarnt, wenn es um die Migration von einer Bibliothek in eine andere geht. Die diskutierten Bibliotheken sind nicht kompatibel - trotz teilweise gleicher Klassennamen.

Intervalle

JSR-310 unterstützt diese Funktion nicht, während Joda-Time nur eingeschränkte Unterstützung bietet. Siehe auch diese SO-Antwort .

Formatieren und Parsen

Der beste Weg, beide Bibliotheken zu vergleichen, besteht darin, die gleichnamigen Klassen DateTimeFormatterBuilder (JSR-310) und DateTimeFormatterBuilder (Joda-Time) anzuzeigen . Die JSR-310-Variante ist etwas leistungsfähiger (kann auch alle Arten von TemporalFieldVorgängen verarbeiten, vorausgesetzt, der Feldimplementierer hat es geschafft, einige Erweiterungspunkte wie resolve () zu codieren ). Der wichtigste Unterschied ist jedoch - meiner Meinung nach:

JSR-310 kann Zeitzonennamen (Formatmustersymbol z) viel besser analysieren, während Joda-Time dies in früheren Versionen und jetzt nur in sehr begrenztem Umfang überhaupt nicht konnte.

Ein weiterer Vorteil von JSR-310 ist die Unterstützung von eigenständigen Monatsnamen, die in Sprachen wie Russisch oder Polnisch usw. wichtig sind. Joda-Time hat keinen Zugriff auf solche Ressourcen - auch nicht auf Java-8-Plattformen.

Die Mustersyntax in JSR-310 ist auch flexibler als in Joda-Time, ermöglicht optionale Abschnitte (in eckigen Klammern), orientiert sich stärker am CLDR-Standard und bietet Auffüllung (Buchstabensymbol p) und mehr Felder.

Andernfalls sollte beachtet werden, dass Joda-Time die Dauer mit PeriodFormatter formatieren kann . JSR-310 kann dies nicht.


Hoffe diese Übersicht hilft. Alle gesammelten Informationen sind hauptsächlich aufgrund meiner Bemühungen und Untersuchungen zum Entwerfen und Implementieren einer besseren Datums- und Zeitbibliothek vorhanden (nichts ist perfekt).

Update vom 24.06.2015:

Inzwischen habe ich die Zeit gefunden , eine tabellarische Übersicht für verschiedene Zeitbibliotheken in Java zu schreiben und zu veröffentlichen . Die Tabellen enthalten auch einen Vergleich zwischen Joda-Time v2.8.1 und Java-8 (JSR-310). Es ist detaillierter als dieser Beitrag.

Meno Hochschild
quelle
12
Dies ist ein hervorragender Beitrag. Vielen Dank, dass Sie all diese Informationen geteilt haben. Wenn Sie die Wahl zwischen Joda und JSR-310 hätten (nur für Vanille-Anwendungsfälle), welche würden Sie wählen? Ich stehe gerade vor dieser Wahl. Ich denke über JSR-310 nach, nur weil es neuer ist und ich versuche, "vorwärts" zu unterstützen, wo immer dies möglich ist.
Kevinarpe
7
@kevinarpe Wenn ich nur die Wahl zwischen JSR-310 und Joda-Time hätte, würde ich JSR-310 wahrscheinlich bevorzugen, da Joda-Time die weitere Entwicklung fast eingestellt hat (neue große Funktionen sind nicht zu erwarten - nur Bugfixing und kleine Updates). Und das Design des JSR-310 ist einfach moderner (und mit besserer interner Qualität). Übrigens und nicht überraschend, meine eigentliche Entscheidung wird eher meine eigene Bibliothek Time4J sein - siehe auch den Link zur tabellarischen Übersicht am Ende meines Beitrags. Es ist immer gut, Alternativen zu haben, und es hängt stark davon ab, welche Funktionen Sie benötigen.
Meno Hochschild
Ist Duration nicht die Java8-Version eines Intervalls?
Christian Hujer
1
@ChristianHujer Nein, java.time.Durationkann im Gegensatz zu einem Intervall, das auf einer Zeitachse verankert ist , nicht nach Anfang oder Ende abgefragt werden. Dieser JSR-310-Typ ist nur ein Paar verstrichener Sekunden und Nanosekunden seit einem unbekannten Start.
Meno Hochschild
42

Java 8 Datum / Uhrzeit:

  1. Java 8-Klassen basieren auf der menschlichen Zeit. Es macht sie schnell für menschliche Datums- / Uhrzeit-Arithmetik / Konvertierung.
  2. Getter für Datums- / getDayOfMonthZeitkomponenten wie O (1) sind in der Java 8-Implementierung komplex.
  3. Das Parsen von OffsetDateTime/ OffsetTime/ ZonedDateTimeist in Java 8 ea b121 aufgrund von Ausnahmen, die intern im JDK ausgelöst und abgefangen werden, sehr langsam.
  4. Eine Reihe von Paketen: java.time.*, java.time.chrono.*, java.time.format.*, java.time.temporal.*,java.time.zone.*
  5. Zeitpunkte (Zeitstempel) Datum und Uhrzeit Teilweise Datums- und Zeitanalyse Parser- und Formatierer-Zeitzonen Unterschiedliche Chronologien (Kalender).
  6. Bestehende Klassen haben Probleme wie Datum, das I18N oder L10N nicht unterstützt. Sie sind veränderlich!
  7. Einfacher und robuster.
  8. Uhren können eingespritzt werden.
  9. Uhren können mit verschiedenen Eigenschaften erstellt werden - statische Uhren, verspottete Uhren, Uhren mit geringer Genauigkeit (ganze Sekunden, ganze Minuten usw.).
  10. Uhren können mit bestimmten Zeitzonen erstellt werden. Clock.system(Zone.of("America/Los_Angeles")).
  11. Macht Datum und Uhrzeit der Codeverarbeitung testbar.
  12. Macht Tests unabhängig von der Zeitzone.

Joda-Zeit:

  1. Joda-Time nutzt die Maschinenzeit im Inneren. Eine manuelle Implementierung basierend auf int / long-Werten wäre viel schneller.
  2. Joda-Time-Getter erfordern die Zeitberechnung von Computer zu Mensch bei jedem Getter-Aufruf, was Joda-Time in solchen Szenarien zu einem Engpass macht.
  3. Es besteht aus unveränderlichen Klassen, die Instanzen, Datum und Uhrzeit, Teilwerte und Dauer verarbeiten. Es ist flexibel und gut gestaltet.
  4. Stellt Daten als Momente dar. Ein Datum und eine Uhrzeit können jedoch mehr als einem Augenblick entsprechen. Überlappungsstunde, wenn die Sommerzeit endet. Sowie keinen Moment haben, der ihm überhaupt entspricht. Lückenstunde, wenn das Tageslicht beginnt. Muss komplexe Berechnungen für einfache Operationen durchführen.
  5. Akzeptiert Nullen als gültige Werte für die meisten Methoden. Führt zu subtilen Fehlern.

Für einen detaillierteren Vergleich siehe: -

Leistung der Java 8-Datums- / Zeitbibliothek (sowie Joda-Time 2.3 und juCalendar) . & Neue Datums- und Uhrzeit-API in Java 8

OO7
quelle
Wenn Sie sagen "Macht Tests unabhängig von der Zeitzone." Was genau meinst du damit?
Zack
@Zack: Wenn Sie Code testen, der sich je nach Zeitzone unterschiedlich verhält, müssen Sie den Test möglicherweise mit einer anderen Standardzeitzone als der vom Betriebssystem bereitgestellten erzwingen.
jarnbjo
Hah - Ich dachte, Sie sagten, dass Joda intern eher auf einer Zeitmaschine als auf Maschinenzeit lief ... Und ich wäre nicht überrascht
Kyranstar
4
@ OO7 Was meinst du mit 'menschlicher Zeit'? Die Zeit wird sowieso von Maschinen berechnet.
IgorGanapolsky
1

Joda-Time ist jetzt im Wartungsmodus

Keine direkte Antwort auf die Frage, aber das Joda-Time- Projekt befindet sich nicht mehr in der aktiven Entwicklung. Das Team schlägt vor, dass Benutzer auf die neuere java.time- API migrieren . Siehe Tutorial von Oracle .

Von der offiziellen GitHub- Projektseite:

Die Joda-Zeit befindet sich nicht mehr in der aktiven Entwicklung, außer um die Zeitzonendaten auf dem neuesten Stand zu halten. Ab Java SE 8 werden Benutzer aufgefordert, auf java.time (JSR-310) zu migrieren - einen Kernbestandteil des JDK, der dieses Projekt ersetzt. Für Android-Benutzer wird java.time in API 26+ hinzugefügt. Projekte, die niedrigere API-Ebenen unterstützen müssen, können die ThreeTenABP-Bibliothek verwenden.

Saikat
quelle