Nouvelle API Date et heure

Chapitre 11. Nouvelle API Date et heure

Ce chapitre couvre

  • Pourquoi nous avions besoin d’une nouvelle bibliothèque de date et heure dans Java 8
  • Représentation de la date et de l’heure pour les humains et machines
  • Définir une durée
  • Manipulation, mise en forme et analyse des dates
  • Traiter avec différents fuseaux horaires et calendriers

L’API Java comprend de nombreux composants utiles pour vous aider à créer des applications complexes. Malheureusement, l’API Java n’est pas toujours parfaite. Nous pensons que la majorité des développeurs Java expérimentés sont d’accord avec le fait que le support de la date et de l’heure avant Java 8 est loin d’être idéal. Ne vous inquiétez pas, cependant; Java 8 introduit une toute nouvelle API Date et heure pour résoudre ce problème.

Dans Java 1.0, le seul support pour la date et l’heure était la classe java.util.Date. Malgré son nom, cette classe ne représente pas une date mais un point dans le temps avec une précision en millisecondes. Pire encore, la facilité d’utilisation de cette classe est compromise par certaines décisions de conception nébuleuses comme le choix de ses compensations: les années commencent à partir de 1900, alors que les mois commencent à l’indice 0. Cela signifie que si vous voulez représenter la date de publication de Java 8 , qui est le 18 mars 2014, vous devez créer une instance de Date comme suit:

L’impression de cette date produit

Pas très intuitif, n’est-ce pas? De plus, même la String retournée par la méthode toString de la classe Date peut être très trompeuse. Il inclut également le fuseau horaire par défaut de la JVM, CET, qui est l’heure d’Europe centrale dans notre cas. Mais cela ne signifie pas que la classe Date elle-même est consciente du fuseau horaire!

Les problèmes et les limitations de la classe Date étaient immédiatement évidents lors de la sortie de Java 1.0, mais il était également clair qu’elle n’était pas réparable sans casser sa rétrocompatibilité. Par conséquent, dans Java 1.1, la plupart des méthodes de la classe Date étaient obsolètes et remplacées par la classe alternative java.util.Calendar. Malheureusement, Calendar a des problèmes similaires et des failles de conception qui conduisent à un code sujet aux erreurs. Par exemple, les mois commencent aussi à l’index 0 (au moins le calendrier s’est débarrassé du décalage de 1900 pour l’année). Pire encore, la présence des classes Date et Calendar augmente la confusion parmi les développeurs. Lequel devriez-vous utiliser? En outre, certaines autres fonctionnalités telles que DateFormat, utilisées pour formater et analyser les dates ou l’heure de manière indépendante du langage, fonctionnent uniquement avec la classe Date.

Le DateFormat vient également avec son propre ensemble de problèmes. Par exemple, il n’est pas thread-safe. Cela signifie que si deux threads essayent d’analyser une date en utilisant le même formateur en même temps, vous pouvez recevoir des résultats imprévisibles.

Enfin, Date et Calendrier sont des classes mutables. Qu’est-ce que cela signifie de muter du 18 mars 2014 au 18 avril? Ce choix de conception peut vous conduire à un cauchemar de maintenance. Vous le verrez plus en détail dans le chapitre suivant,  sur la programmation fonctionnelle.

La conséquence est que toutes ces failles et incohérences ont encouragé l’utilisation de bibliothèques tierces, telles que Joda-Time. Pour ces raisons, Oracle a décidé de fournir un support de date et d’heure de haute qualité dans l’API Java native. Par conséquent, Java 8 intègre de nombreuses fonctionnalités Joda-Time dans le package java.time.

Dans ce chapitre, nous explorerons les fonctionnalités introduites par la nouvelle API Date et heure. Nous commençons par des cas d’utilisation basiques tels que la création de dates et d’heures pouvant être utilisées par des humains et des machines, et explorerons progressivement des applications plus avancées de la nouvelle API Date et Heure, comme manipuler, analyser et imprimer des objets date / heure. travailler avec différents fuseaux horaires et calendriers alternatifs.

12.1. LocalDate, LocalTime, Instant, Durée et Période

Commençons par explorer comment créer des dates et des intervalles simples. Le package java.time inclut de nombreuses nouvelles classes pour vous aider: LocalDate, LocalTime, LocalDateTime, Instant, Durée et Période.

12.1.1. Travailler avec LocalDate et LocalTime

La classe LocalDate est probablement la première que vous rencontrerez lorsque vous commencerez à utiliser la nouvelle API Date et heure. Une instance de cette classe est un objet immuable représentant simplement une date sans heure de la journée. En particulier, il ne contient aucune information sur le fuseau horaire.

Vous pouvez créer une instance LocalDate en utilisant la méthode factory statique of. Une instance LocalDate fournit de nombreuses méthodes pour lire ses valeurs les plus couramment utilisées, telles que l’année, le mois, le jour de la semaine, etc., comme indiqué dans le schéma qui suit.

Schéma 12.1. Créer un LocalDate et lire ses valeurs

Il est également possible d’obtenir la date actuelle à partir de l’horloge système en utilisant la méthode statique now :

Toutes les autres classes de date-heure que nous étudierons dans la partie restante de ce chapitre fournissent une méthode factory similaire. Vous pouvez également accéder aux mêmes informations en transmettant un TemporalField à la méthode get. TemporalField est une interface qui définit comment accéder à la valeur d’un champ spécifique d’un objet temporel. L’énumération ChronoField implémente cette interface, de sorte que vous pouvez facilement utiliser un élément de cette énumération avec la méthode get, comme indiqué dans le schéma suivant.

Schéma 12.2. Lecture des valeurs LocalDate à l’aide d’un TemporalField

De même, l’heure du jour, telle que 13:45:20, est représentée par la classe LocalTime. Vous pouvez créer des instances de LocalTime en utilisant deux méthodes factory statiques surchargées nommées of. Le premier accepte une heure et une minute et le second en accepte une seconde. Tout comme la classe LocalDate, la classe LocalTime fournit des méthodes getter pour accéder à ses valeurs, comme indiqué dans le schéma suivant.

Schéma 12.3. Créer un LocalTime et lire ses valeurs

LocalDate et LocalTime peuvent être créés en parsant une String les représentant. Vous pouvez y parvenir en utilisant leurs méthodes d’analyse syntaxique:

Il est possible de passer un DateTimeFormatter à la méthode parse. Une instance de cette classe spécifie comment formater une date et / ou un objet temporel. Il est destiné à remplacer l’ancien java.util.DateFormat que nous avons mentionné plus tôt. Nous montrons plus en détail comment vous pouvez utiliser un DateTimeFormatter dans la section 12.2. Notez également que ces méthodes d’analyse lancent toutes deux une DateTimeParseException, qui étend RuntimeException, dans le cas où l’argument String ne peut pas être parsé en tant que LocalDate ou LocalTime valide.

12.1.2. Combiner une date et une heure

La classe composite appelée LocalDateTime associe un LocalDate et un LocalTime. Il représente à la fois une date et une heure, sans fuseau horaire, et peut être créé directement ou en combinant une date et une heure, comme indiqué dans la figure suivante.

Figure 12.4. Créer un LocalDateTime directement ou en combinant une date et une heure

Notez qu’il est possible de créer un LocalDateTime en passant une heure à une LocalDate, ou inversement une date à un LocalTime, en utilisant respectivement leurs méthodes atTime ou atDate. Vous pouvez également extraire le composant LocalDate ou LocalTime d’un LocalDateTime en utilisant les méthodes toLocalDate et :

12.1.3. Instant: une date et une heure pour les machines

En tant qu’êtres humains, nous sommes habitués à penser aux dates et heures en termes de semaines, de jours, d’heures et de minutes. Néanmoins, cette représentation n’est pas facile à gérer pour un ordinateur. Du point de vue de la machine, le format le plus naturel pour modéliser le temps est avec un seul grand nombre représentant un point sur une ligne de temps continue. C’est l’approche utilisée par la nouvelle classe java.time.Instant, qui représente essentiellement le nombre de secondes écoulées depuis l’époque Unix, fixée par convention à minuit le 1er janvier 1970 UTC.

Vous pouvez créer une instance de cette classe en transmettant le nombre de secondes à sa méthode factory statique ofEpochSecond. En outre, la classe Instant prend en charge la précision de la nanoseconde. Il existe une version supplémentaire surchargée de la méthode statique ofEpochSecond qui accepte un deuxième argument qui est un ajustement de la nanoseconde au nombre de secondes écoulé. Cette version surchargée ajuste l’argument de la nanoseconde, en s’assurant que la fraction nanoseconde stockée est entre 0 et 999 999 999. Cela signifie que toutes les invocations suivantes de la méthode ofEpochSecond retourneront exactement le même Instant:

Comme vous l’avez déjà vu pour le LocalDate et les autres classes date-heure lisibles par l’homme, la classe Instant prend également en charge une autre méthode statique nommée now, qui vous permet de capturer un horodatage du moment actuel. Il est important de souligner qu’un Instant est destiné à être utilisé uniquement par une machine. Il se compose d’un certain nombre de secondes et de nanosecondes. Par conséquent, il ne permet pas de gérer des unités de temps significatives pour les humains. Par exemple, cette déclaration

va juste jeter une exception comme

Mais vous pouvez travailler avec Instants en utilisant les classes Durattion et Périod, que nous verrons ensuite.

12.1.4. Définir une durée ou une période

Toutes les classes que vous avez vues jusqu’ici implémentent l’interface Temporal, qui définit comment lire et manipuler les valeurs d’un objet modélisant un point générique dans le temps. Nous vous avons montré plusieurs façons de créer différentes instances de Temporal. L’étape naturelle suivante consiste à créer une durée entre deux objets temporels. La méthode statique between la classe Duration sert exactement ce but. Vous pouvez créer une durée entre deux LocalTimes, deux LocalDateTimes ou deux Instants comme suit:

Parce que LocalDateTime et Instant sont faits à des fins différentes, l’un devant être utilisé par les humains et l’autre par les machines, vous n’êtes pas autorisé à les mélanger. Si vous essayez de créer une durée entre eux, vous obtiendrez uniquement une DateTimeException. De plus, étant donné que la classe Duration est utilisée pour représenter une durée mesurée en secondes et éventuellement en nanosecondes, vous ne pouvez pas passer une valeur LocalDate à la méthode between.

Lorsque vous devez modéliser une durée en termes d’années, de mois et de jours, vous pouvez utiliser la classe Period. Vous pouvez trouver la différence entre deux LocalDates avec la méthode between de cette classe:

Enfin, les deux classes Duration et Period ont d’autres méthodes pratiques pour créer des instances directement, en d’autres termes, sans les définir comme la différence entre deux objets temporels, comme indiqué dans la figure suivante.
Figure 12.5. Créer des durées et des périodes

Les classes Duration et Period partagent toutes deux des méthodes similaires, et le tableau 12.1 les répertorie.
Tableau 12.1. Les méthodes courantes des classes date-heure représentant un intervalle

Toutes les classes que nous avons étudiées jusqu’à présent sont immuables, et c’est un excellent choix de conception pour permettre un style de programmation plus fonctionnel, garantir la sécurité des threads et préserver la cohérence du modèle de domaine. Néanmoins, la nouvelle API Date et Heure propose des méthodes pratiques pour créer une version modifiée de ces objets. Par exemple, vous pouvez ajouter trois jours à une instance LocalDate existante. Nous explorons comment faire cela dans la section suivante. En outre, nous explorons comment créer un formateur date-heure à partir d’un modèle donné, tel que jj / MM / aaaa, ou même par programmation, et comment utiliser ce formateur à la fois pour le parsing et l’impression d’une date.

12.2. Manipulation, parsing et mise en forme des dates

La façon la plus immédiate et la plus facile de créer une version modifiée d’une LocalDate existante consiste à modifier l’un de ses attributs en utilisant l’une de ses méthodes withAttribute. Notez que toutes les méthodes retournent un nouvel objet avec l’attribut modifié, comme indiqué dans la figure suivante. Ils ne muent pas l’objet existant!

Figure 12.6. Manipuler les attributs d’un LocalDate de manière absolue

Vous pouvez également le faire avec la méthode générique with, en prenant un TemporalField comme premier argument, comme dans la dernière déclaration de la figure 12.6. Ce dernier with est le dual de la méthode get utilisée dans la figure 12.2. Ces deux méthodes sont déclarées dans l’interface Temporal implémentée par toutes les classes de l’API Date et heure, qui définissent un seul point dans le temps, tel que LocalDate, LocalTime, LocalDateTime et Instant. Plus précisément, les méthodes get et with vous permettent respectivement de lire et de modifier la valeur d’un champ d’un objet Temporel. Ils lancent une exception Unsupported-TemporalTypeException si le champ demandé n’est pas pris en charge par le paramètre Temporal spécifique, par exemple ChronoField.MONTH_OF_YEAR sur Instant ou ChronoField.NANO _OF_SECOND sur LocalDate.

Il est même possible de manipuler un LocalDate de manière déclarative. Par exemple, vous pouvez ajouter ou soustraire une durée donnée, comme indiqué dans la figure suivante.
Figure 12.7. Manipuler les attributs d’un LocalDate d’une manière relative

De manière similaire à ce que nous avons expliqué à propos des méthodes with et get, la méthode générique plus utilisée dans la dernière déclaration de la figure 12.7, de façon analogue avec la méthode minus , est déclarée dans l’interface Temporal. Ces méthodes vous permettent de reculer ou d’avancer un Temporal, défini par un nombre plus une unité temporelle, où l’énumération ChronoUnit offre une implémentation pratique de l’interface TemporalUnit.

Comme vous l’avez peut-être prévu, toutes les classes de date-heure représentant un point dans le temps comme LocalDate, LocalTime, LocalDateTime et Instant ont de nombreuses méthodes en commun; le tableau 12.2 les résume.

Tableau 12.2. Les méthodes courantes des classes date-heure représentant un point dans le temps

Vérifiez ce que vous avez appris jusqu’à présent sur la manipulation des dates avec le Quiz 12.1.



Quiz 12.1: Manipuler un LocalDate

Quelle sera la valeur de la variable de date après les manipulations suivantes?

Réponse:

Comme vous l’avez vu, vous pouvez manipuler la date à la fois d’une manière absolue et d’une manière relative. Vous pouvez également concaténer plus de manipulations dans une seule instruction, car chaque modification créera un nouvel objet LocalDate et l’invocation suivante manipulera l’objet créé par l’ancien. Enfin, la dernière instruction de cet extrait de code n’a aucun effet observable car, comme d’habitude, elle crée une nouvelle instance LocalDate, mais nous n’attribuons pas cette nouvelle valeur à une variable.



12.2.1. Travailler avec TemporalAdjusters

Toutes les manipulations de date que vous avez vues jusqu’ici sont relativement simples. Parfois, vous devrez peut-être effectuer des opérations plus avancées, telles que l’ajustement d’une date au dimanche suivant, au jour ouvrable suivant ou au dernier jour du mois. Dans de tels cas, vous pouvez passer un TemporalAdjuster à une version surchargée de la méthode with,  qui fournit un moyen plus personnalisable de définir la manipulation nécessaire pour d’obtenir une date spécifique. L’API Date et Heure fournit déjà de nombreux Ajusteurs temporels prédéfinis pour les cas d’utilisation les plus courants. Vous pouvez y accéder en utilisant les méthodes statiques contenues dans la classe TemporalAdjusters, comme indiqué ci-dessous.

Figure 12.8. Utilisation des TemporalAdjusters prédéfinis

Le Tableau 12.3 fournit une liste des TemporalAdjusters pouvant être créés avec ces méthodes.

Tableau 12.3. Les méthodes de la classe TemporalAdjusters

Comme vous pouvez le voir, TemporalAdjusters vous permet d’effectuer des manipulations de date plus complexes qui se lisent toujours comme l’énoncé du problème. De plus, il est relativement simple de créer votre propre implémentation personnalisée de TemporalAdjuster si vous ne trouvez pas un TemporalAdjuster prédéfini qui corresponde à vos besoins. En fait, l’interface TemporalAdjuster ne déclare qu’une seule méthode (ce qui en fait une interface fonctionnelle), définie comme suit.

Figure 12.9. L’interface TemporalAdjuster

Cela signifie qu’une implémentation de l’interface TemporalAdjuster définit comment convertir un objet Temporal en un autre Temporal. Vous pouvez le considérer comme étant un UnaryOperator <Temporel>. Prenez quelques minutes pour mettre en pratique ce que vous avez appris jusqu’à présent et implémentez votre propre TemporalAdjuster dans le Quiz 12.2.



Quiz 12.2: Implémentation d’un TemporalAdjuster personnalisé

Développez une classe nommée NextWorkingDay, en implémentant l’interface TemporalAdjuster qui déplace une date vers l’avant d’une journée, mais ignore les samedis et dimanches. Faire ce qui suit

devrait déplacer la date au jour suivant, si ce jour est entre lundi et vendredi, mais au lundi suivant si c’est un samedi ou un dimanche.

Réponse:

Vous pouvez implémenter NextWorkingDay comme suit:

Ce TemporalAdjuster déplace normalement une date vers l’avant d’un jour, sauf si aujourd’hui c’est un vendredi ou un samedi, auquel cas il avance les dates de trois ou deux jours, respectivement. Notez que, comme un TemporalAdjuster est une interface fonctionnelle, vous pouvez simplement passer le comportement de cet ajusteur dans une expression lambda:

Il est probable que vous souhaitiez appliquer cette manipulation à une date en plusieurs points de votre code, et pour cette raison nous vous suggérons d’encapsuler sa logique dans une classe appropriée comme nous l’avons fait ici. Faites de même pour toutes les manipulations que vous utilisez fréquemment. Vous vous retrouverez avec une petite bibliothèque d’ajusteurs que vous et votre équipe pourriez facilement réutiliser dans votre code.

Si vous voulez définir le TemporalAdjuster avec une expression lambda, il est préférable de le faire en utilisant la méthode statique ofDateAdjuster de la classe TemporalAdjusters qui accepte un UnaryOperator<LocalDate> comme suit:



Une autre opération courante que vous pouvez effectuer sur vos objets de date et d’heure consiste à les imprimer dans différents formats spécifiques à votre domaine d’activité. De même, vous pouvez convertir les String représentant des dates dans ces formats en objets de date réels. Dans la section suivante, nous démontrerons les mécanismes fournis par la nouvelle API Date et Heure pour accomplir ces tâches.

12.2.2. Impression et analyse d’objets date-heure

La mise en forme et le parsing sont une autre fonctionnalité pertinente lorsque vous travaillez avec des dates et des heures. Le nouveau package java.time.format est entièrement consacré à cette fin. La classe la plus importante de ce package est DateTimeFormatter. La méthode la plus simple pour créer un formateur consiste à utiliser ses méthodes et constantes statiques. Les constantes telles que BASIC_ISO_DATE et ISO_LOCAL_DATE ne sont que des instances prédéfinies de la classe DateTimeFormatter. Tous les DateTimeFormatters peuvent être utilisés pour créer une chaîne représentant une date ou une heure donnée dans un format spécifique. Par exemple, ici nous produisons une String en utilisant deux formats différents:

Vous pouvez également analyser une String représentant une date ou une heure dans ce format pour recréer l’objet date lui-même. Vous pouvez y parvenir en utilisant la méthode parse factory fournie par toutes les classes de l’API Date et heure représentant un point dans le temps ou un intervalle:

Par rapport à l’ancienne classe java.util.DateFormat, toutes les instances DateTimeFormatter sont compatibles avec les threads. Par conséquent, vous pouvez créer des formateurs singleton, comme ceux définis par les constantes DateTimeFormatter, et les partager entre plusieurs threads. La classe DateTimeFormatter prend également en charge une méthode statique qui vous permet de créer un formateur à partir d’un modèle spécifique, comme illustré dans la figure suivante.
Figure 12.10. Création d’un horodatage DateTimeFormatter à partir d’un pattern

Ici, la méthode de format de LocalDate produit une chaîne représentant la date avec le modèle demandé. Ensuite, la méthode de parsing statique récré la même date en parsant la String générée en utilisant le même formateur. La méthode ofPattern a également une version surchargée vous permettant de créer un formateur pour un environnement local donné, comme indiqué dans la figure suivante.

Figure 12.11. Création d’un DateTimeFormatter localisé

Enfin, au cas où vous auriez besoin de plus de contrôle, la classe DateTimeFormatterBuilder vous permet de définir des formateurs complexes étape par étape en utilisant des méthodes significatives. En outre, il vous offre la possibilité d’effectuer un parsing insensible à la casse, un parsing tolérant(permettant au parseur d’utiliser des heuristiques pour interpréter les entrées qui ne correspondent pas exactement au format spécifié), un remplissage et des sections optionnelles du formateur. Par exemple, vous pouvez créer par programme le même italianFormatter que nous avons utilisé dans la figure 12.11 via DateTimeFormatterBuilder comme suit.

Figure 12.12. Construire un DateTimeFormatter

Jusqu’à présent, vous avez appris à créer, manipuler, formater et parser les deux points dans le temps et les intervalles. Mais vous n’avez pas vu comment faire face à des subtilités impliquant des dates et des heures. Par exemple, vous devrez peut-être gérer différents fuseaux horaires ou travailler avec des systèmes de calendrier différents. Dans les sections suivantes, nous explorons ces sujets en utilisant la nouvelle API Date et heure.

12.3. Travailler avec différents fuseaux horaires et calendriers

Aucune des classes que vous avez vues jusqu’à présent ne contenait d’informations sur les fuseaux horaires. Traiter les fuseaux horaires est un autre problème important qui a été grandement simplifié par la nouvelle API Date et Heure. La nouvelle classe java.time.ZoneId remplace l’ancienne classe java.util.TimeZone. Il vise à mieux vous protéger des complexités liées aux fuseaux horaires, telles que le traitement de l’heure d’été (DST). Comme les autres classes de l’API Date et Heure, elle est immuable.

Un fuseau horaire est un ensemble de règles correspondant à une région dans laquelle l’heure standard est la même. Il y en a environ 40 dans les instances de la classe ZoneRules. Vous pouvez simplement appeler getRules() sur un ZoneId pour obtenir les règles pour ce fuseau horaire donné. Un ZoneId spécifique est identifié par un ID de région, par exemple:

Les ID de région sont tous au format « {area}/{city} » et l’ensemble des emplacements disponibles est celui fourni par la base de données de fuseaux horaires de l’IANA. Vous pouvez également convertir un ancien objet TimeZone en ZoneId en utilisant la nouvelle méthode toZoneId:

Une fois que vous avez un objet ZoneId, vous pouvez le combiner avec LocalDate, LocalDateTime ou Instant, pour le transformer en instances ZonedDateTime, qui représentent des points dans le temps par rapport au fuseau horaire spécifié, comme indiqué dans la figure suivante.
Figure 12.13. Appliquer un fuseau horaire à un moment donné

La Figure 12.1 illustre les composants d’un ZonedDateTime pour vous aider à comprendre les différences entre LocaleDate, LocalTime, LocalDateTime et ZoneId.

Figure 12.1. Donner du sens à un ZonedDateTime

Vous pouvez également convertir un LocalDateTime en Instant en utilisant un ZoneId:

Ou vous pouvez le faire dans l’autre sens:

12.3.1. Correction de décalage d’UTC / Greenwich

Une autre façon courante d’exprimer un fuseau horaire est avec un décalage fixe par rapport à UTC / Greenwich. Par exemple, vous pouvez utiliser cette notation pour dire que « New York est à cinq heures de Londres ». Dans ce cas, vous pouvez utiliser la classe ZoneOffset, une sous-classe de ZoneId qui représente la différence entre un temps et le méridien zéro de Greenwich, Londres:

Le décalage de -05: 00 correspond en effet à l’heure normale de l’Est des États-Unis. Sachez qu’un ZoneOffset défini de cette manière n’a pas de gestion de l’heure d’été, et pour cette raison, il n’est pas recommandé dans la majorité des cas. Parce qu’un ZoneOffset est également un ZoneId, vous pouvez l’utiliser comme indiqué dans la figure 12.13. Vous pouvez également créer un OffsetDateTime, qui représente une date-heure avec un décalage d’UTC/Greenwich dans le système de calendrier ISO-8601:

Une autre fonctionnalité avancée prise en charge par la nouvelle API Date et heure est la prise en charge des systèmes d’agenda non ISO.

12.3.2. Utilisation de systèmes de calendrier alternatifs

Le système de calendrier ISO-8601 est le système de calendrier civil du monde entier. Mais quatre systèmes de calendrier supplémentaires sont fournis dans Java 8. Chacun de ces systèmes de calendrier a une classe de date dédiée: ThaiBuddhistDate, MinguoDate, JapaneseDate et HijrahDate. Toutes ces classes avec LocalDate implémentent l’interface ChronoLocalDate destinée à modéliser une date dans une chronologie arbitraire. Vous pouvez créer une instance de l’une de ces classes à partir d’une LocalDate. Plus généralement, vous pouvez créer n’importe quelle autre instance temporelle en utilisant leurs méthodes statiques comme suit:

Vous pouvez également créer explicitement un système de calendrier pour une Locale spécifique et créer une instance d’une date pour cette Locale. Dans la nouvelle API Date et heure, l’interface Chronology modélise un système de calendrier et vous pouvez en obtenir une instance à l’aide de la méthode statique ofLocale :

Les concepteurs de l’API Date et Heure conseillent d’utiliser LocalDate au lieu de Chrono-LocalDate dans la plupart des cas; C’est parce qu’un développeur pourrait faire des suppositions dans leur code qui, malheureusement, ne sont pas vraies dans un système multicalendar. De telles hypothèses peuvent inclure que la valeur d’un jour ou d’un mois ne sera jamais supérieure à 31, qu’une année contient 12 mois, ou même qu’une année a un nombre fixe de mois. Pour ces raisons, il est recommandé d’utiliser LocalDate dans toute votre application, y compris le stockage, la manipulation et l’interprétation des règles métier, alors que vous ne devez utiliser Chrono-LocalDate que lorsque vous devez localiser l’entrée ou la sortie de votre programme.

Calendrier islamique

Sur les nouveaux calendriers ajoutés à Java 8, le HijrahDate (calendrier islamique) semble être le plus complexe car il peut avoir des variantes. Le système de calendrier Hijrah est basé sur les mois lunaires. Il existe plusieurs méthodes pour déterminer un nouveau mois, comme une nouvelle lune qui pourrait être visible n’importe où dans le monde ou qui doit être visible d’abord en Arabie Saoudite. La méthode withVariant est utilisée pour choisir la variante désirée. Java 8 a inclus la variante Umm Al-Qura pour HijrahDate comme standard.

Le code suivant illustre un exemple d’affichage des dates de début et de fin du Ramadan pour l’année islamique en cours en date ISO:

12.4. Résumé

Dans ce chapitre, vous avez appris ce qui suit:

  • L’ancienne classe java.util.Date et toutes les autres classes utilisées pour modéliser la date et l’heure en Java avant Java 8 présentent de nombreuses incohérences et failles de conception, notamment leur mutabilité et certains décalages, valeurs par défaut et noms mal choisis.
  • Les objets date-heure de la nouvelle API Date et heure sont tous immuables.
  • Cette nouvelle API fournit deux représentations temporelles différentes pour gérer les différents besoins des humains et des machines lors de leur fonctionnement.
  • Vous pouvez manipuler les objets de date et d’heure de manière absolue et relative, et le résultat de ces manipulations est toujours une nouvelle instance, laissant l’original inchangé.
  • TemporalAdjusters vous permet de manipuler une date d’une manière plus complexe que de simplement changer une de ses valeurs, et vous pouvez définir et utiliser vos propres transformations de date personnalisées.
  • Vous pouvez définir un formateur pour imprimer et parser les objets date-heure dans un format spécifique. Ces formateurs peuvent être créés à partir d’un modèle ou par programmation et ils sont tous thread-safe.
  • Vous pouvez représenter un fuseau horaire, à la fois relatif à une région/un emplacement spécifique et en tant que décalage fixe par rapport à UTC / Greenwich, et l’appliquer à un objet date-heure afin de le localiser.
  • Vous pouvez utiliser des systèmes de calendrier différents du système standard ISO-8601.