Différences entre l'API Java 8 Date Time (java.time) et Joda-Time

264

Je sais qu'il y a des questions concernant java.util.Date et Joda-Time. Mais après quelques recherches, je n'ai pas trouvé de fil sur les différences entre l' API java.time (nouvelle dans Java 8 , définie par JSR 310 ) et Joda-Time .

J'ai entendu dire que l'API java.time de Java 8 est beaucoup plus propre et peut faire bien plus que Joda-Time. Mais je ne trouve pas d'exemples comparant les deux.

  • Que peut faire java.time que Joda-Time ne peut pas faire?
  • Qu'est-ce que java.time peut faire de mieux que Joda-Time?
  • Les performances sont-elles meilleures avec java.time?
Zack
la source
8
Ce n'est pas le cas, qui concerne Java 7, pas Java 8. La réponse à cette question a été modifiée pour Java 8 avec très très peu de détails. Ma question concerne spécifiquement la nouvelle API DateTime de Java 8, et non java.util.Date de Java 7. Je cherche juste une réponse qui compare Java 8 à JodaTime.
Zack
2
peut - être ce document Oracle peut vous aider.
MarioDS
Si vous avez Java 7, utilisez la bibliothèque supplémentaire, si vous avez Java 8, utilisez la bibliothèque intégrée. Étant donné que les deux bibliothèques sont essentiellement conçues par la même personne, je ne sais pas quelles différences majeures vous attendez.
Peter Lawrey du
2
@PeterLawrey: Joda-Time et l'API de date et d'heure Java 8 sont en fait assez différents.
jarnbjo
5
Vous pouvez également lire cet article de blog de Stephen Colbourne - l'auteur principal des deux projets.
Matt Johnson-Pint

Réponses:

416

Caractéristiques communes

a) Les deux bibliothèques utilisent des types immuables. Joda-Time propose également des types mutables supplémentaires comme MutableDateTime.

b) En outre: Les deux bibliothèques sont inspirées par l'étude de conception "TimeAndMoney" d'Eric Evans ou les idées de Martin Fowler sur le style piloté par domaine afin qu'elles s'efforcent plus ou moins pour un style de programmation fluide (bien que pas toujours parfait ;-)).

c) Avec les deux bibliothèques, nous obtenons un type de date de calendrier réel (appelé LocalDate), un type d'heure de mur réel (appelé LocalTime) et la composition (appelée LocalDateTime). C'est une très grosse victoire par rapport aux anciens java.util.Calendaret aux java.util.Date.

d) Les deux bibliothèques utilisent une approche centrée sur la méthode, ce qui signifie qu'elles encouragent l'utilisateur à utiliser à la getDayOfYear()place de get(DAY_OF_YEAR). Cela entraîne beaucoup de méthodes supplémentaires par rapport à java.util.Calendar(bien que cette dernière ne soit pas du tout sûre pour le type en raison d'une utilisation excessive des pouces).

Performance

Voir l'autre réponse de @ OO7 pointant vers l'analyse de Mikhail Vorontsov bien que le point 3 (capture d'exception) soit probablement obsolète - voir ce bug JDK . Les performances différentes (qui sont en général en faveur de JSR-310 ) sont principalement dues au fait que l'implémentation interne de Joda-Time utilise toujours une primitive longue de type machine (en millisecondes).

Nul

Joda-Time utilise souvent NULL par défaut pour le fuseau horaire du système, les paramètres régionaux par défaut, l'horodatage actuel, etc. tandis que JSR-310 rejette presque toujours les valeurs NULL.

Précision

JSR-310 gère la précision en nanosecondes tandis que Joda-Time est limité à la précision en millisecondes .

Champs pris en charge:

Un aperçu des champs pris en charge dans Java-8 (JSR-310) est donné par certaines classes du package temporel (par exemple ChronoField et WeekFields ) tandis que Joda-Time est plutôt faible dans ce domaine - voir DateTimeFieldType . Le plus grand manque de Joda-Time est ici l'absence de champs localisés liés à la semaine. Une caractéristique commune de la conception d'implémentation des deux champs est que les deux sont basés sur des valeurs de type long (pas d'autres types, pas même des énumérations).

Enum

JSR-310 propose des énumérations comme DayOfWeekou Monthalors que Joda-Time ne le propose pas car il a été principalement développé dans les années 2002-2004 avant Java 5 .

API de zone

a) JSR-310 offre plus de fonctionnalités de fuseau horaire que Joda-Time. Latter n'est pas en mesure de fournir un accès par programmation à l'historique des transitions de décalage de fuseau horaire tandis que le JSR-310 est capable de le faire.

b) Pour votre information: JSR-310 a déplacé son référentiel de fuseau horaire interne vers un nouvel emplacement et un format différent. L'ancien dossier de bibliothèque lib / zi n'existe plus.

Ajusteur vs propriété

JSR-310 a introduit TemporalAdjuster-l'interface comme un moyen formalisé d'externaliser les calculs et les manipulations temporelles, en particulier pour les rédacteurs de bibliothèques ou de frameworks. cours pour anciens java.util.Date).

Cependant, pour la plupart des utilisateurs, cette fonctionnalité a une valeur très limitée car la charge d'écrire du code incombe toujours à l'utilisateur. Les solutions intégrées basées sur le nouveau TemporalAdjuster-concept ne sont pas si nombreuses, il n'y a actuellement que la classe d'assistance TemporalAdjustersavec un ensemble limité de manipulations (et les énumérations Monthou autres types temporels).

Joda-Time propose un package de terrain, mais la pratique a montré que les nouvelles implémentations de terrain sont très difficiles à coder. D'un autre côté, Joda-Time propose des soi-disant propriétés qui rendent certaines manipulations beaucoup plus faciles et plus élégantes que dans JSR-310, par exemple property.withMaximumValue () .

Systèmes de calendrier

JSR-310 propose 4 systèmes de calendrier supplémentaires. Le plus intéressant est Umalqura (utilisé en Arabie Saoudite). Les 3 autres sont: Minguo (Taiwan), japonais (seulement le calendrier moderne depuis 1871!) Et ThaiBuddhist (seulement correct après 1940).

Joda-Time propose un calendrier islamique basé sur une base de calcul - pas un calendrier basé sur l'observation comme Umalqura. Thai-Buddhist est également proposé par Joda-Time sous une forme similaire, Minguo et japonais non. Sinon, Joda-Time propose également un calendrier copte et éthiopique (mais sans aucun support pour l'internationalisation).

Plus intéressant pour les Européens: Joda-Time propose également un calendrier grégorien , julien et grégorien-julien mixte. Cependant, la valeur pratique pour les calculs historiques réels est limitée car des caractéristiques importantes telles que les différentes années de début dans l'historique des dates ne sont pas du tout prises en charge (la même critique est valable pour les anciens java.util.GregorianCalendar).

D'autres calendriers comme l' hébreu ou le persan ou l' hindou manquent complètement dans les deux bibliothèques.

Jours d'époque

JSR-310 a la classe JulianFields tandis que Joda-Time (version 2.0) propose des méthodes d'assistance dans la classe DateTimeUtils .

Horloges

JSR-310 n'a pas d'interface (une erreur de conception) mais une classe abstraite java.time.Clockqui peut être utilisée pour toute injection de dépendance d'horloge. Joda-Time propose à la place l'interface MillisProvider et certaines méthodes d'assistance dans DateTimeUtils . Ainsi, Joda-Time est également capable de prendre en charge des modèles pilotés par les tests avec différentes horloges (moqueries, etc.).

Durée arithmétique

Les deux bibliothèques prennent en charge le calcul des distances temporelles dans une ou plusieurs unités temporelles. Cependant, lors de la gestion de durées d'une seule unité, le style JSR-310 est évidemment plus agréable (et basé sur une longue au lieu d'utiliser int):

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

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

La gestion des durées à unités multiples est également différente. Même les résultats des calculs peuvent différer - voir ce problème Joda-Time fermé . Alors que JSR-310 utilise une approche très simple et limitée pour utiliser uniquement les classes Period(durée basée sur les années, les mois et les jours) et Duration(basée sur les secondes et les nanosecondes), Joda-Time utilise une manière plus sophistiquée en utilisant la classe PeriodTypeafin de contrôler dans quelles unités une durée (Joda-Time l'appelle "Période") doit être exprimée. Tandis que lePeriodType-API est en quelque sorte difficile à utiliser d'une manière similaire n'est pas du tout proposé par JSR-310. Surtout, il n'est pas encore possible dans JSR-310 de définir des durées de date et d'heure mixtes (basées sur les jours et les heures par exemple). Soyez donc prévenu en cas de migration d'une bibliothèque à une autre. Les bibliothèques en discussion sont incompatibles - malgré des noms de classe partiellement identiques.

Intervalles

JSR-310 ne prend pas en charge cette fonction tandis que Joda-Time a un support limité. Voir aussi cette réponse SO .

Formatage et analyse

La meilleure façon de comparer les deux bibliothèques consiste à afficher les classes de nom égal DateTimeFormatterBuilder (JSR-310) et DateTimeFormatterBuilder (Joda-Time). La variante JSR-310 est un peu plus puissante (peut également gérer n'importe quel type à TemporalFieldcondition que l'implémentateur de champ ait réussi à coder certains points d'extension comme resolver () ). La différence la plus importante est cependant - à mon avis:

JSR-310 peut mieux analyser les noms de fuseau horaire (symbole de modèle de format z) tandis que Joda-Time ne pouvait pas du tout le faire dans ses versions antérieures et maintenant seulement de manière très limitée.

Un autre avantage de JSR-310 est la prise en charge des noms de mois autonomes, ce qui est important dans des langues comme le russe ou le polonais, etc. Joda-Time n'a pas accès à ces ressources - pas même sur les plates-formes Java-8.

La syntaxe de modèle dans JSR-310 est également plus flexible que dans Joda-Time, permet des sections optionnelles (en utilisant des crochets), est plus orientée vers la norme CLDR et offre un remplissage (symbole de lettre p) et plus de champs.

Sinon, il convient de noter que Joda-Time peut formater les durées à l'aide de PeriodFormatter . JSR-310 ne peut pas faire cela.


J'espère que cet aperçu vous aidera. Toutes les informations recueillies sont principalement là grâce à mes efforts et à mes recherches pour concevoir et implémenter une meilleure bibliothèque de date et d'heure (rien n'est parfait).

Mise à jour du 24/06/2015:

En attendant, j'ai trouvé le temps d'écrire et de publier un aperçu tabulaire pour différentes bibliothèques de temps en Java. Les tableaux contiennent également une comparaison entre Joda-Time v2.8.1 et Java-8 (JSR-310). Il est plus détaillé que ce billet.

Meno Hochschild
la source
12
Il s'agit d'un poste exceptionnel. Merci beaucoup de partager toutes ces informations. Si vous aviez le choix entre Joda et JSR-310 (pour les cas d'utilisation de vanille uniquement), lequel choisiriez-vous? Je fais face à ce choix en ce moment. J'envisage le JSR-310, uniquement parce qu'il est plus récent et j'essaye de soutenir "aller de l'avant" chaque fois que possible.
kevinarpe
7
@kevinarpe Si je n'avais que le choix entre JSR-310 et Joda-Time, je préférerais probablement JSR-310 parce que Joda-Time a presque arrêté tout développement ultérieur (de nouvelles fonctionnalités importantes ne peuvent pas être attendues - juste la correction de bugs et de petites mises à jour). Et la conception du JSR-310 est tout simplement plus moderne (et avec une meilleure qualité interne). Soit dit en passant et sans surprise cependant, ma vraie décision va plutôt préférer ma propre bibliothèque Time4J - voir aussi le lien vers l'aperçu tabulaire donné au bas de mon post. Il est toujours bon d'avoir des alternatives, et cela dépend fortement des fonctionnalités dont vous avez besoin.
Meno Hochschild
La durée n'est-elle pas la version Java8 d'un intervalle?
Christian Hujer
1
@ChristianHujer Non, java.time.Durationne peut pas être interrogé pour son début ou sa fin, contrairement à un intervalle qui est ancré sur une chronologie. Ce type JSR-310 n'est qu'une paire de secondes et de nanosecondes écoulées depuis un démarrage inconnu.
Meno Hochschild
42

Date / heure Java 8:

  1. Les classes Java 8 sont construites autour du temps humain. Il les rend rapides pour l'arithmétique / conversion humaine datetime.
  2. Les getters de composants de date / heure comme getDayOfMonthont une complexité O (1) dans l'implémentation de Java 8.
  3. L'analyse de OffsetDateTime/ OffsetTime/ ZonedDateTimeest très lente dans Java 8 ea b121 en raison d'exceptions levées et interceptées en interne dans le JDK.
  4. Un ensemble de paquets: java.time.*, java.time.chrono.*, java.time.format.*, java.time.temporal.*,java.time.zone.*
  5. Instants (horodatages) Date et heure Date et heure partielles Analyseur et formateur Fuseaux horaires Différentes chronologies (calendriers).
  6. Les classes existantes ont des problèmes tels que Date ne prend pas en charge I18N ou L10N. Ils sont mutables!
  7. Plus simple et plus robuste.
  8. Des horloges peuvent être injectées.
  9. Les horloges peuvent être créées avec diverses propriétés - horloges statiques, horloges simulées, horloges de faible précision (secondes entières, minutes entières, etc.).
  10. Les horloges peuvent être créées avec des fuseaux horaires spécifiques. Clock.system(Zone.of("America/Los_Angeles")).
  11. Rend la date et l'heure de manipulation du code testables.
  12. Rend les tests indépendants du fuseau horaire.

Joda-Time:

  1. Joda-Time utilise le temps machine à l'intérieur. Une implémentation manuelle basée sur des valeurs int / long serait beaucoup plus rapide.
  2. Les getters Joda-Time nécessitent le calcul du temps de l'ordinateur à l'homme à chaque appel getter, ce qui fait de Joda-Time un goulot d'étranglement dans de tels scénarios.
  3. Il est composé de classes immuables, il gère les instants, la date et l'heure, les partiels et les durées. Il est flexible. Il est bien conçu.
  4. Représente les dates sous forme d'instants. Mais une date et une heure peuvent correspondre à plus d'un instant. Heure de chevauchement à la fin de l'heure d'été. En plus de n'avoir aucun instant qui lui correspond. Heure Gap lorsque la lumière du jour commence. Doit effectuer des calculs complexes pour des opérations simples.
  5. Accepte les valeurs NULL comme valeurs valides sur la plupart de ses méthodes. Conduit à des bugs subtils.

Pour une comparaison plus détaillée, voir: -

Performances de la bibliothèque Java 8 Date / Time (ainsi que Joda-Time 2.3 et juCalendar) . & Nouvelle API de date et d'heure dans Java 8

OO7
la source
Lorsque vous dites "Rend les tests indépendants du fuseau horaire". Que voulez-vous dire exactement par là?
Zack
@Zack: Probablement que si vous testez du code, qui se comporte différemment selon le fuseau horaire, vous devrez peut-être forcer l'exécution du test avec un fuseau horaire par défaut différent de celui fourni par le système d'exploitation.
jarnbjo
Hah - Je pensais que tu avais dit que joda fonctionnait en interne sur une machine à remonter le temps plutôt que sur le temps machine ... Et je ne serais pas surpris
Kyranstar
4
@ OO7 Que voulez-vous dire par «temps humain»? Le temps est de toute façon calculé par les machines.
IgorGanapolsky
1

Joda-Time est maintenant en mode maintenance

Pas une réponse directe à la question mais le projet Joda-Time n'est plus en développement actif. L'équipe suggère aux utilisateurs de migrer vers la nouvelle API java.time . Voir le didacticiel d'Oracle .

Depuis la page officielle du projet GitHub :

Joda-time n'est plus en développement actif, sauf pour maintenir les données de fuseau horaire à jour. À partir de Java SE 8, les utilisateurs sont invités à migrer vers java.time (JSR-310) - une partie centrale du JDK qui remplace ce projet. Pour les utilisateurs d'Android, java.time est ajouté dans l'API 26+. Les projets devant prendre en charge des niveaux d'API inférieurs peuvent utiliser la bibliothèque ThreeTenABP.

Saikat
la source