Differenze tra l'API Java 8 Date Time (java.time) e Joda-Time


264

So che ci sono domande relative a java.util.Date e Joda-Time. Ma dopo alcuni scavi, non sono riuscito a trovare un thread sulle differenze tra l' API java.time (nuova in Java 8 , definita da JSR 310 ) e Joda-Time .

Ho sentito che l'API java.time di Java 8 è molto più pulita e può fare molto di più di Joda-Time. Ma non riesco a trovare esempi confrontando i due.

  • Cosa può fare java.time che Joda-Time non può fare?
  • Cosa può fare java.time meglio di Joda-Time?
  • Le prestazioni sono migliori con java.time?

8
Non è pertinente a Java 7, non a Java 8. La risposta a questa domanda è stata modificata per Java 8 con pochissimi dettagli. La mia domanda riguarda in particolare la nuova API DateTime di Java 8, non java.util.Date di Java 7. Sto solo cercando una risposta che paragona Java 8 a JodaTime.
Zack,

2
forse questo documento Oracle può aiutarti.
MarioDS,

Se si dispone di Java 7, utilizzare la libreria aggiuntiva, se si dispone di Java 8, utilizzare la libreria integrata. Poiché entrambe le librerie sono fondamentalmente progettate dalla stessa persona, non sono sicuro di quali siano le principali differenze che ti aspetti.
Peter Lawrey,

2
@PeterLawrey: Joda-Time e l'API di data e ora di Java 8 sono in realtà abbastanza diversi.
jarnbjo,

5
Puoi anche leggere questo post sul blog di Stephen Colbourne, l'autore principale di entrambi i progetti.
Matt Johnson-Pint,

Risposte:


416

Caratteristiche comuni

a) Entrambe le librerie usano tipi immutabili. Joda-Time offre anche altri tipi mutabili come MutableDateTime.

b) Inoltre: entrambe le librerie sono ispirate allo studio di design "TimeAndMoney" di Eric Evans o alle idee di Martin Fowler sullo stile guidato dal dominio, quindi si sforzano più o meno per uno stile di programmazione fluente (anche se non sempre perfetto ;-)).

c) Con entrambe le librerie otteniamo un tipo di data di calendario reale (chiamato LocalDate), un tipo di ora di muro reale (chiamato LocalTime) e la composizione (chiamata LocalDateTime). Questa è una vittoria molto grande rispetto al vecchio java.util.Calendare java.util.Date.

d) Entrambe le librerie utilizzano un approccio incentrato sul metodo, il che significa che incoraggiano l'utente a utilizzare getDayOfYear()invece di get(DAY_OF_YEAR). Ciò comporta molti metodi aggiuntivi rispetto a java.util.Calendar(sebbene quest'ultimo non sia affatto sicuro per il tipo a causa dell'uso eccessivo di ints).

Prestazione

Vedi l'altra risposta di @ OO7 che punta all'analisi di Mikhail Vorontsov sebbene il punto 3 (rilevazione delle eccezioni) sia probabilmente obsoleto - vedi questo bug JDK . Le diverse prestazioni (che sono generalmente a favore di JSR-310 ) sono dovute principalmente al fatto che l'implementazione interna di Joda-Time utilizza sempre una primitiva lunga simile al tempo macchina (in millisecondi).

Nullo

Joda-Time spesso utilizza NULL come predefinito per fuso orario di sistema, impostazioni internazionali predefinite, data e ora corrente, mentre JSR-310 rifiuta quasi sempre i valori NULL.

Precisione

JSR-310 gestisce la precisione dei nanosecondi mentre Joda-Time è limitato alla precisione dei millisecondi .

Campi supportati:

Una panoramica sui campi supportati in Java-8 (JSR-310) è fornita da alcune classi nel pacchetto temporale (ad esempio ChronoField e WeekFields ) mentre Joda-Time è piuttosto debole in quest'area - vedi DateTimeFieldType . La più grande mancanza di Joda-Time è qui l'assenza di campi localizzati relativi alla settimana. Una caratteristica comune di entrambi i progetti di implementazione del campo è che entrambi sono basati su valori di tipo long (nessun altro tipo, nemmeno enumerazioni).

enum

JSR-310 offre enum come DayOfWeeko Monthmentre Joda-Time non lo offre perché è stato sviluppato principalmente negli anni 2002-2004 prima di Java 5 .

API di zona

a) JSR-310 offre più funzioni di fuso orario rispetto a Joda-Time. Latter non è in grado di fornire un accesso programmatico alla cronologia delle transizioni di offset del fuso orario mentre JSR-310 è in grado di farlo.

b) Per tua informazione: JSR-310 ha spostato il suo repository interno del fuso orario in una nuova posizione e in un formato diverso. La vecchia cartella della libreria lib / zi non esiste più.

Aggiustatore vs. Proprietà

JSR-310 ha introdotto l' TemporalAdjusterinterfaccia come un modo formalizzato per esternalizzare calcoli e manipolazioni temporali, specialmente per gli scrittori di librerie o di quadri, questo è un modo semplice e relativamente semplice per incorporare nuove estensioni di JSR-310 (una sorta di equivalente a supporto statico lezioni per ex java.util.Date).

Per la maggior parte degli utenti, tuttavia, questa funzione ha un valore molto limitato poiché l'onere della scrittura del codice è ancora a carico dell'utente. Le soluzioni integrate basate sul nuovo TemporalAdjusterconcetto non sono così tante, al momento esiste solo la classe helper TemporalAdjusterscon un set limitato di manipolazioni (e gli enum Montho altri tipi temporali).

Joda-Time offre un pacchetto sul campo ma la pratica ha dimostrato che le nuove implementazioni sul campo sono molto difficili da codificare. Dall'altro lato, Joda-Time offre le cosiddette proprietà che rendono alcune manipolazioni molto più semplici ed eleganti rispetto a JSR-310, ad esempio property.withMaximumValue () .

Sistemi di calendario

JSR-310 offre 4 sistemi di calendario extra. Il più interessante è Umalqura (usato in Arabia Saudita). Gli altri 3 sono: Minguo (Taiwan), giapponese (solo il calendario moderno dal 1871!) E ThaiBuddhist (corretto solo dopo il 1940).

Joda-Time offre un calendario islamico basato sulla base di calcolo, non un calendario basato sugli avvistamenti come Umalqura. Il buddista thailandese è anche offerto da Joda-Time in una forma simile, Minguo e quella giapponese no. Altrimenti Joda-Time offre anche un calendario copto ed etiopico (ma senza alcun supporto per l'internazionalizzazione).

Più interessante per gli europei: Joda-Time offre anche un calendario gregoriano , giuliano e misto-gregoriano-giuliano. Tuttavia, il valore pratico per i calcoli storici reali è limitato perché funzioni importanti come l'inizio di un anno diverso nella cronologia delle date non sono affatto supportate (la stessa critica è valida per i vecchi java.util.GregorianCalendar).

Altri calendari come l' ebraico o il persiano o l' indù mancano completamente in entrambe le biblioteche.

Giorni di epoca

JSR-310 ha la classe JulianFields mentre Joda-Time (versione 2.0) offre alcuni metodi di supporto nella classe DateTimeUtils .

orologi

JSR-310 non ha un'interfaccia (un errore di progettazione) ma una classe astratta java.time.Clockche può essere utilizzata per qualsiasi iniezione di dipendenza dell'orologio. Joda-Time offre invece l'interfaccia MillisProvider e alcuni metodi di supporto in DateTimeUtils . In questo modo Joda-Time è anche in grado di supportare modelli test-driven con orologi diversi (beffardo ecc.).

Durata aritmetica

Entrambe le librerie supportano il calcolo delle distanze temporali in una o più unità temporali. Tuttavia, quando si gestiscono durate a unità singola, lo stile JSR-310 è ovviamente più bello (e basato su lunghi invece di usare int):

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

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

Anche la gestione delle durate di più unità è diversa. Anche i risultati del calcolo possono differire: vedi questo problema di Joda-Time chiuso . Mentre JSR-310 usa un approccio molto semplice e limitato per usare solo le classi Period(durata basata su anni, mesi e giorni) e Duration(basato su secondi e nanosecondi), Joda-Time usa un modo più sofisticato usando la classe PeriodTypeper controllare in quali unità deve essere espressa una durata (Joda-Time chiamalo "Periodo"). Mentre ilPeriodType-API è in qualche modo imbarazzante usare un modo simile non è offerto da JSR-310. In particolare, nel JSR-310 non è ancora possibile definire la durata mista di data e ora (ad esempio in base a giorni e ore). Quindi avvisati se si tratta di migrazione da una libreria all'altra. Le biblioteche in discussione sono incompatibili, nonostante i nomi di classe parzialmente uguali.

intervalli

JSR-310 non supporta questa funzione mentre Joda-Time ha un supporto limitato. Vedi anche questa risposta SO .

Formattazione e analisi

Il modo migliore per confrontare entrambe le librerie è visualizzare le classi con nomi uguali DateTimeFormatterBuilder (JSR-310) e DateTimeFormatterBuilder (Joda-Time). La variante JSR-310 è un po 'più potente (può anche gestire qualsiasi tipo di TemporalFieldcondizione che l'implementatore di campo sia riuscito a codificare alcuni punti di estensione come resol () ). La differenza più importante è tuttavia - secondo me:

JSR-310 è in grado di analizzare molto meglio i nomi di fuso orario (simbolo del modello di formato z) mentre Joda-Time non potrebbe farlo affatto nelle sue versioni precedenti e ora solo in modo molto limitato.

Un altro vantaggio di JSR-310 è il supporto per i nomi dei mesi standalone che è importante in lingue come il russo o il polacco, ecc. Joda-Time non ha accesso a tali risorse , nemmeno su piattaforme Java-8.

La sintassi del pattern in JSR-310 è anche più flessibile rispetto a Joda-Time, consente sezioni opzionali (usando parentesi quadre), è più orientata verso lo standard CLDR e offre imbottitura (simbolo della lettera p) e più campi.

Altrimenti, va notato che Joda-Time può formattare le durate usando PeriodFormatter . JSR-310 non può farlo.


Spero che questa panoramica sia di aiuto. Tutte le informazioni raccolte sono principalmente lì a causa dei miei sforzi e delle mie indagini su come progettare e implementare una migliore libreria di data e ora (niente è perfetto).

Aggiornamento dal 24/06/2015:

Nel frattempo ho trovato il tempo di scrivere e pubblicare una panoramica tabellare per diverse librerie del tempo in Java. Le tabelle contengono anche un confronto tra Joda-Time v2.8.1 e Java-8 (JSR-310). È più dettagliato di questo post.


12
Questo è un post eccezionale. Mille grazie per condividere tutte queste informazioni. Se fosse data la scelta tra Joda e JSR-310 (solo per casi d'uso vaniglia), quale sceglieresti? Sto affrontando questa scelta in questo momento. Sto prendendo in considerazione JSR-310, solo perché è più recente e cerco di supportare "andare avanti", ove possibile.
kevinarpe,

7
@kevinarpe Se avessi solo la scelta tra JSR-310 e Joda-Time probabilmente preferirei JSR-310 perché Joda-Time ha quasi interrotto qualsiasi ulteriore sviluppo (non ci si può aspettare nuove grandi funzionalità - solo correzioni di bug e piccoli aggiornamenti). E il design di JSR-310 è semplicemente più moderno (e con una migliore qualità interna). A proposito e comunque non sorprendente, la mia vera decisione è piuttosto quella di preferire la mia biblioteca Time4J - vedi anche il link alla panoramica tabellare riportata in fondo al mio post. È sempre utile disporre di alternative e dipende fortemente dalle funzionalità di cui hai bisogno.
Meno Hochschild,

La durata non è la versione Java8 di un intervallo?
Christian Hujer,

1
@ChristianHujer No, java.time.Durationnon è possibile eseguire query per l'inizio o la fine, a differenza di un intervallo ancorato su una sequenza temporale. Questo tipo JSR-310 è solo una coppia di secondi e nanosecondi trascorsi da un inizio sconosciuto.
Meno Hochschild,

42

Data / ora Java 8:

  1. Le classi Java 8 sono costruite attorno al tempo umano. Li rende veloci per l'aritmetica / conversione del datetime umano.
  2. I getter di componenti data / ora getDayOfMonthhanno una complessità O (1) nell'implementazione di Java 8.
  3. L'analisi di OffsetDateTime/ OffsetTime/ ZonedDateTimeè molto lenta in Java 8 ea b121 a causa di eccezioni generate e catturate internamente nel JDK.
  4. Un insieme di pacchetti: java.time.*, java.time.chrono.*, java.time.format.*, java.time.temporal.*,java.time.zone.*
  5. Instants (timestamps) Data e ora Data e ora parziali Farser e formatter Fusi orari Cronologie diverse (calendari).
  6. Le classi esistenti hanno problemi come Date non ha supporto per I18N o L10N. Sono mutabili!
  7. Più semplice e più robusto.
  8. Gli orologi possono essere iniettati.
  9. Gli orologi possono essere creati con varie proprietà: orologi statici, orologi simulati, orologi a bassa precisione (secondi interi, minuti interi, ecc.).
  10. Gli orologi possono essere creati con fusi orari specifici. Clock.system(Zone.of("America/Los_Angeles")).
  11. Rende testabile la data e l'ora di gestione del codice.
  12. Rende i test indipendenti dal fuso orario.

Joda-Time:

  1. Joda-Time sta usando il tempo macchina all'interno. Un'implementazione manuale basata su valori int / long sarebbe molto più veloce.
  2. I getter Joda-Time richiedono il calcolo del tempo da computer a uomo su ogni chiamata getter, il che rende Joda-Time un collo di bottiglia in tali scenari.
  3. È composto da classi immutabili che gestisce istanti, data e ora, parziali e durate È flessibile È ben progettato.
  4. Rappresenta le date come istanti. Ma una data e ora possono corrispondere a più di un istante. Ora di sovrapposizione alla fine dell'ora legale. Oltre a non avere nessun istante che gli corrisponda affatto. Ora spalancata quando inizia la luce del giorno. Deve eseguire calcoli complessi per operazioni semplici.
  5. Accetta i valori null come valori validi sulla maggior parte dei suoi metodi. Porta a bug sottili.

Per un confronto più dettagliato vedere: -

Prestazioni della libreria data / ora di Java 8 (oltre a Joda-Time 2.3 e juCalendar) . & Nuova data e ora API in Java 8


Quando dici "Rende i test indipendenti dal fuso orario". Cosa intendi esattamente con questo?
Zack,

@Zack: probabilmente se si esegue il test del codice, che si comporta in modo diverso a seconda del fuso orario, potrebbe essere necessario forzare l'esecuzione del test con un fuso orario predefinito diverso da quello fornito dal sistema operativo.
jarnbjo,

Hah - Pensavo avessi detto che Joda correva internamente su una macchina del tempo piuttosto che sul tempo della macchina ... E non sarei sorpreso
Kyranstar

4
@ OO7 Cosa intendi per "tempo umano"? Il tempo viene comunque calcolato dalle macchine.
IgorGanapolsky,

1

Joda-Time è ora in modalità manutenzione

Non è una risposta diretta alla domanda, ma il progetto Joda-Time non è più in fase di sviluppo attivo. Il team suggerisce agli utenti di migrare alla nuova API java.time . Vedi tutorial di Oracle .

Dalla pagina ufficiale del progetto GitHub :

Joda-time non è più in sviluppo attivo se non per mantenere aggiornati i dati del fuso orario. Da Java SE 8 in poi, agli utenti viene chiesto di migrare a java.time (JSR-310), una parte fondamentale di JDK che sostituisce questo progetto. Per gli utenti Android, java.time viene aggiunto nell'API 26+. I progetti che necessitano di supportare livelli API inferiori possono utilizzare la libreria ThreeTenABP.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.