Différences entre l’API de date et heure de Java 8 (java.time) et Joda-Time

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 conducteur sur les différences entre l’ API java.time (nouveauté de Java 8 , définie par JSR 310 ) et Joda-Time .

J’ai entendu que l’API java.time de Java 8 était beaucoup plus propre et pouvait faire beaucoup plus que Joda-Time. Mais je ne peux pas trouver d’exemples comparant les deux.

  • Que peut faire java.time avec Joda-Time?
  • Que peut faire java.time mieux que Joda-Time?
  • La performance est-elle meilleure avec java.time?

Caractéristiques communes

a) Les deux bibliothèques utilisent des types immuables. Joda-Time offre également des types de mutables supplémentaires tels que MutableDateTime .

b) En outre: les deux bibliothèques s’inspirent de l’étude de conception “TimeAndMoney” d’Eric Evans ou des idées de Martin Fowler sur le style piloté par domaine . Elles cherchent donc plus ou moins un style de programmation courant (pas toujours parfait ;-)).

c) Avec les deux bibliothèques, nous obtenons un type de date réel (appelé LocalDate ), un type de temps de mur réel (appelé LocalTime ) et la composition (appelée LocalDateTime ). C’est un très gros gain comparé aux anciens java.util.Calendar et java.util.Date .

d) Les deux bibliothèques utilisent une approche centrée sur les méthodes, ce qui signifie qu’elles encouragent l’utilisateur à utiliser getDayOfYear() au lieu de get(DAY_OF_YEAR) . Cela entraîne beaucoup de méthodes supplémentaires par rapport à java.util.Calendar (bien que cette méthode ne soit pas du tout sécurisée en raison de l’utilisation excessive d’ints).

Performance

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

Nul

Joda-Time utilise souvent NULL par défaut pour le fuseau horaire du système, les parameters 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 à la nanoseconde tandis que Joda-Time est limitée à la précision en milliseconde .

Champs pris en charge:

Une vue d’ensemble des champs pris en charge dans Java-8 (JSR-310) est donnée par certaines classes du package temporal (par exemple ChronoField et WeekFields ) alors que Joda-Time est plutôt faible sur cette zone – voir DateTimeFieldType . Le plus grand manque de Joda-Time est l’absence de champs localisés liés à la semaine. Une caractéristique commune de la conception de l’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 DayOfWeek comme DayOfWeek ou Month alors que Joda-Time ne l’offre pas car il a été principalement développé dans les années 2002-2004 avant Java 5 .

Zone API

a) JSR-310 offre plus de fonctionnalités de fuseau horaire que Joda-Time. Le dernier n’est pas capable de fournir un access programmé à l’historique des transitions de décalage de fuseau horaire alors que 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 l’interface TemporalAdjuster comme moyen formalisé d’extérioriser les calculs et les manipulations temporels, en particulier pour les librairies ou les rédacteurs de framework. Il s’agit d’un moyen simple et relativement simple d’intégrer de nouvelles extensions de JSR-310 classes d’assistance pour l’ancien java.util.Date ).

Pour la plupart des utilisateurs, cependant, cette fonctionnalité a une valeur très limitée car l’utilisateur doit toujours écrire le code. Les solutions intégrées basées sur le nouveau concept TemporalAdjuster ne sont pas très nombreuses, il n’y a actuellement que les ajusteurs TemporalAdjusters classe d’assistance avec un ensemble limité de manipulations (et les Month énumérés ou d’autres types temporels).

Joda-Time propose un paquetage sur le terrain, mais la pratique a prouvé que les nouvelles implémentations de champs sont très difficiles à coder. De l’autre côté, Joda-Time propose des propriétés qui facilitent certaines manipulations et les rendent plus élégantes que dans JSR-310, par exemple property.withMaximumValue () .

Systèmes de calendrier

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

Joda-Time propose un calendrier islamique basé sur une base de calcul – et non un calendrier basé sur l’observation comme Umalqura. Thai-Buddhist est également proposé par Joda-Time sous une forme similaire, Minguo et le japonais non. Sinon Joda-Time propose aussi 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 mixte-grégorien-julien. Cependant, la valeur pratique pour les calculs historiques réels est limitée car les fonctionnalités importantes comme les débuts d’année dans l’historique des dates ne sont pas du tout sockets en charge (la même critique est valable pour l’ancien java.util.GregorianCalendar ).

D’autres calendriers comme l’ hébreu ou le persan ou l’ hindou sont complètement absents des 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 .

Les horloges

JSR-310 n’a pas d’interface (une erreur de conception) mais une classe abstraite java.time.Clock qui peut être utilisée pour toute dependency injection 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 testés avec des horloges différentes (moqueur, etc.).

Arithmétique de durée

Les deux bibliothèques prennent en charge le calcul des distances de temps dans une ou plusieurs unités temporelles. Cependant, lors du traitement de durées unitaires, le style JSR-310 est évidemment plus agréable (et basé sur une longue utilisation que sur 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 du calcul 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 méthode plus sophistiquée afin de contrôler dans quelles unités une durée (Joda-Time l’appelle “Période”) doit être exprimée. Alors que le PeriodType -API est quelque peu difficile à utiliser, JSR-310 ne propose pas du tout le PeriodType procédé. En particulier, il n’est pas encore possible dans JSR-310 de définir des durées mixtes de date et d’heure (basées sur des jours et des heures par exemple). Alors, soyez prévenu s’il s’agit d’une migration d’une bibliothèque à une autre. Les bibliothèques en discussion sont incompatibles – malgré des noms de classes partiellement identiques.

Les intervalles

JSR-310 ne prend pas en charge cette fonctionnalité alors que Joda-Time dispose d’un support limité. Voir aussi cette réponse SO .

Formatage et parsing

La meilleure façon de comparer les deux bibliothèques consiste à afficher les classes de même nom DateTimeFormatterBuilder (JSR-310) et DateTimeFormatterBuilder (Joda-Time). La variante JSR-310 est un peu plus puissante (peut également gérer n’importe quel type de TemporalField condition que l’implémenteur de champ ait réussi à coder des points d’extension tels que resolve () ). La différence la plus importante est cependant – à mon avis:

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

Un autre avantage de JSR-310 est le support des noms de mois autonomes, ce qui est important dans des langues comme le russe ou le polonais, etc. Joda-Time n’a pas access à de telles ressources , même sur les plates-formes Java-8.

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

Sinon, il convient de noter que Joda-Time peut formater des durées en utilisant PeriodFormatter . JSR-310 ne peut pas faire cela.


J’espère que cette vue d’ensemble aide. Toutes les informations recueillies sont principalement dues à mes efforts et mes investigations sur la manière de concevoir et d’implémenter une meilleure bibliothèque de date et heure (rien n’est parfait).

Mise à jour du 2015-06-24:

Pendant ce temps, 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). C’est plus détaillé que ce post.

Java 8 Date / Heure:

  1. Les classes Java 8 sont construites autour du temps humain. Cela les rend rapides pour l’arithmétique / conversion de datetime humain.
  2. Les getters de composant date / heure comme getDayOfMonth ont une getDayOfMonth O (1) dans l’implémentation de Java 8.
  3. L’parsing de OffsetDateTime / OffsetTime / ZonedDateTime est très lente dans Java 8 et b121 en raison des exceptions lancé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 Partiel Date et heure Analyseur et formateur Fuseaux horaires Chronologies différentes (calendriers).
  6. Les classes existantes ont des problèmes comme Date n’a pas de support pour I18N ou L10N. Ils sont mutables!
  7. Plus simple et plus robuste.
  8. Les horloges peuvent être injectées.
  9. Des horloges peuvent être créées avec différentes 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. Permet de tester la date et l’heure de manipulation du code.
  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 les valeurs int / long serait beaucoup plus rapide.
  2. Les getters Joda-Time exigent le calcul du temps entre ordinateurs pour chaque appel, 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, date et heure, partiels et durées Il est flexible Il est bien conçu.
  4. Représente les dates comme des instants. Mais une date et une heure peuvent correspondre à plus d’un instant. Heure de chevauchement lorsque l’heure d’été se termine. De même que ne pas avoir d’instant qui lui correspond du tout. Heure d’ouverture lorsque le jour commence. A effectuer des calculs complexes pour des opérations simples.
  5. Accepte les valeurs nulles comme valeurs valides sur la plupart de ses méthodes. Conduit à des bogues 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