Guide de DateTimeFormatter

1. Vue d'ensemble

Dans ce didacticiel, nous passerons en revue la classe Java 8 DateTimeFormatter et ses modèles de mise en forme . Nous allons également discuter des cas d'utilisation possibles pour cette classe.

Nous pouvons utiliser DateTimeFormatter pour formater uniformément les dates et les heures dans une application avec des modèles prédéfinis ou définis par l'utilisateur.

2. DateTimeFormatter avec des instances prédéfinies

DateTimeFormatter est livré avec plusieurs formats de date / heure prédéfinis qui respectent les normes ISO et RFC. Par exemple, nous pouvons utiliser l'instance ISO_LOCAL_DATE pour analyser une date telle que '2018-03-09':

DateTimeFormatter.ISO_LOCAL_DATE.format(LocalDate.of(2018, 3, 9));

Pour analyser une date avec un décalage, nous pouvons utiliser ISO_OFFSET_DATE pour obtenir une sortie comme '2018-03-09-03: 00':

DateTimeFormatter.ISO_OFFSET_DATE.format(LocalDate.of(2018, 3, 9).atStartOfDay(ZoneId.of("UTC-3")));

La plupart des instances prédéfinies de la classe DateTimeFormatter se concentrent sur la norme ISO-8601. ISO-8601 est une norme internationale pour le formatage de la date et de l'heure.

Il existe cependant une instance prédéfinie différente qui analyse la RFC-1123, Requirement for Internet Hosts, publiée par l'IETF:

DateTimeFormatter.RFC_1123_DATE_TIME.format(LocalDate.of(2018, 3, 9).atStartOfDay(ZoneId.of("UTC-3")));

Cet extrait génère " Fri, 9 Mar 2018 00:00:00 -0300 ".

Parfois, nous devons manipuler la date que nous recevons sous la forme d'une chaîne d'un format connu. Nous pouvons utiliser la méthode parse () :

LocalDate.from(DateTimeFormatter.ISO_LOCAL_DATE.parse("2018-03-09")).plusDays(3);

Le résultat de cet extrait de code est une représentation LocalDate du 12 mars 2018.

3. DateTimeFormatter avec FormatStyle

Parfois, nous souhaitons imprimer les dates de manière lisible par l'homme.

Dans de tels cas, nous pouvons utiliser les valeurs java.time.format.FormatStyle enum (FULL, LONG, MEDIUM, SHORT) avec notre DateTimeFormatter :

LocalDate anotherSummerDay = LocalDate.of(2016, 8, 23); System.out.println(DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL).format(anotherSummerDay)); System.out.println(DateTimeFormatter.ofLocalizedDate(FormatStyle.LONG).format(anotherSummerDay)); System.out.println(DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM).format(anotherSummerDay)); System.out.println(DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT).format(anotherSummerDay));

La sortie de ces différents styles de mise en forme de la même date est:

Tuesday, August 23, 2016 August 23, 2016 Aug 23, 2016 8/23/16

Nous pouvons également utiliser des styles de mise en forme prédéfinis pour la date et l'heure. Pour utiliser FormatStyle avec le temps, nous devrons utiliser l' instance ZonedDateTime , sinon, une DateTimeException sera lancée:

LocalDate anotherSummerDay = LocalDate.of(2016, 8, 23); LocalTime anotherTime = LocalTime.of(13, 12, 45); ZonedDateTime zonedDateTime = ZonedDateTime.of(anotherSummerDay, anotherTime, ZoneId.of("Europe/Helsinki")); System.out.println( DateTimeFormatter.ofLocalizedDateTime(FormatStyle.FULL) .format(zonedDateTime)); System.out.println( DateTimeFormatter.ofLocalizedDateTime(FormatStyle.LONG) .format(zonedDateTime)); System.out.println( DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM) .format(zonedDateTime)); System.out.println( DateTimeFormatter.ofLocalizedDateTime(FormatStyle.SHORT) .format(zonedDateTime));

Notez que nous avons utilisé cette fois la méthode ofLocalizedDateTime () de DateTimeFormatter .

Et le résultat que nous obtenons est:

Tuesday, August 23, 2016 1:12:45 PM EEST August 23, 2016 1:12:45 PM EEST Aug 23, 2016 1:12:45 PM 8/23/16 1:12 PM

Nous pouvons également utiliser FormatStyle pour analyser une chaîne de date et d'heure en la convertissant en ZonedDateTime , par exemple.

Nous pouvons ensuite utiliser la valeur analysée pour manipuler la variable de date et d'heure:

ZonedDateTime dateTime = ZonedDateTime.from( DateTimeFormatter.ofLocalizedDateTime(FormatStyle.FULL) .parse("Tuesday, August 23, 2016 1:12:45 PM EET")); System.out.println(dateTime.plusHours(9));

La sortie de cet extrait est «2016-08-23T22: 12: 45 + 03: 00 [Europe / Bucarest]», notez que l'heure a changé en «22:12:45».

4. DateTimeFormatter avec des formats personnalisés

Les formateurs et styles prédéfinis et intégrés peuvent couvrir de nombreuses situations . Cependant, nous devons parfois formater une date et une heure quelque peu différemment. C'est à ce moment que les modèles de formatage personnalisés entrent en jeu.

4.1. DateTimeFormatter pour la date

Supposons que nous voulions présenter un objet java.time.LocalDate en utilisant un format européen normal comme 31.12.2018. Pour ce faire, nous pourrions appeler la méthode de fabrique DateTimeFormatter . ofPattern ("jj.MM.aaaa").

Cela créera une instance DateTimeFormatter appropriée que nous pouvons utiliser pour formater notre date:

String europeanDatePattern = "dd.MM.yyyy"; DateTimeFormatter europeanDateFormatter = DateTimeFormatter.ofPattern(europeanDatePattern); System.out.println(europeanDateFormatter.format(LocalDate.of(2016, 7, 31)));

La sortie de cet extrait de code sera «31.07.2016».

Il existe de nombreuses lettres de modèle différentes que nous pouvons utiliser pour créer un format de dates qui répondra à nos besoins:

 Symbol Meaning Presentation Examples ------ ------- ------------ ------- u year year 2004; 04 y year-of-era year 2004; 04 M/L month-of-year number/text 7; 07; Jul; July; J d day-of-month number 10

Ceci est un extrait de la documentation Java officielle de la classe DateTimeFormatter .

Le nombre de lettres dans le format du motif est significatif .

Si nous utilisons un modèle à deux lettres pour le mois, nous obtiendrons une représentation du mois à deux chiffres. Si le numéro du mois est inférieur à 10, il sera complété par un zéro. Lorsque nous n'avons pas besoin du remplissage mentionné avec des zéros, nous pouvons utiliser un modèle à une lettre «M», qui affichera janvier comme «1».

Si nous utilisons un modèle à quatre lettres pour le mois, «MMMM», alors nous obtiendrons une représentation «pleine forme». Dans notre exemple, c'est «juillet». Un modèle de 5 lettres, «MMMMM», obligera le formateur à utiliser la «forme étroite». Dans notre cas, «J» serait utilisé.

De même, un modèle de mise en forme personnalisé peut également être utilisé pour analyser une chaîne contenant une date:

DateTimeFormatter europeanDateFormatter = DateTimeFormatter.ofPattern("dd.MM.yyyy"); System.out.println(LocalDate.from(europeanDateFormatter.parse("15.08.2014")).isLeapYear());

Cet extrait de code vérifie si la date « 15.08.2014 » fait partie d'une année bissextile, et ce n'est pas le cas.

4.2. DateTimeFormatter pour l'heure

Il existe également des lettres de modèle qui peuvent être utilisées pour les modèles de temps:

 Symbol Meaning Presentation Examples ------ ------- ------------ ------- H hour-of-day (0-23) number 0 m minute-of-hour number 30 s second-of-minute number 55 S fraction-of-second fraction 978 n nano-of-second number 987654321

Il est assez simple d'utiliser DateTimeFormatter pour formater une instance java.time.LocalTime . Supposons que nous voulions afficher l'heure (heures, minutes et secondes) délimitée par deux points:

String timeColonPattern = "HH:mm:ss"; DateTimeFormatter timeColonFormatter = DateTimeFormatter.ofPattern(timeColonPattern); LocalTime colonTime = LocalTime.of(17, 35, 50); System.out.println(timeColonFormatter.format(colonTime));

Cela générera la sortie « 17:35:50 ».

Si nous voulons ajouter des millisecondes à la sortie, nous devons ajouter «SSS» au modèle:

String timeColonPattern = "HH:mm:ss SSS"; DateTimeFormatter timeColonFormatter = DateTimeFormatter.ofPattern(timeColonPattern); LocalTime colonTime = LocalTime.of(17, 35, 50).plus(329, ChronoUnit.MILLIS); System.out.println(timeColonFormatter.format(colonTime));

Ce qui donne la sortie " 17:35:50 329 ".

Notez que «HH» est un modèle d'heure du jour qui génère la sortie de 0-23. Lorsque nous voulons afficher AM / PM, nous devons utiliser «hh» minuscule pendant des heures et ajouter un modèle «a»:

String timeColonPattern = "hh:mm:ss a"; DateTimeFormatter timeColonFormatter = DateTimeFormatter.ofPattern(timeColonPattern); LocalTime colonTime = LocalTime.of(17, 35, 50); System.out.println(timeColonFormatter.format(colonTime));

La sortie générée est « 05:35:50 PM ».

We may want to parse time String with our custom formatter and check if it is before noon:

DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("hh:mm:ss a"); System.out.println(LocalTime.from(timeFormatter.parse("12:25:30 AM")).isBefore(LocalTime.NOON));

The output of this last snippet shows that the given time is actually before noon.

4.3. DateTimeFormatter for Time Zones

Often we want to see a time zone of some specific date-time variable. If we happen to use New York-based date-time (UTC -4), we may use “z” pattern-letter for time-zone name:

String newYorkDateTimePattern = "dd.MM.yyyy HH:mm z"; DateTimeFormatter newYorkDateFormatter = DateTimeFormatter.ofPattern(newYorkDateTimePattern); LocalDateTime summerDay = LocalDateTime.of(2016, 7, 31, 14, 15); System.out.println(newYorkDateFormatter.format(ZonedDateTime.of(summerDay, ZoneId.of("UTC-4"))));

This will generate the output “31.07.2016 14:15 UTC-04:00”.

We can parse date time strings with time zones just like we did earlier:

DateTimeFormatter zonedFormatter = DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm z"); System.out.println(ZonedDateTime.from(zonedFormatter.parse("31.07.2016 14:15 GMT+02:00")).getOffset().getTotalSeconds());

The output of this code is “7200” seconds, or 2 hours, as we'd expect.

Nous devons nous assurer que nous fournissons une chaîne de date et d'heure correcte à la méthode parse () . Si nous passons «31.07.2016 14:15», sans fuseau horaire, au zonedFormatter du dernier extrait de code, nous obtiendrons une DateTimeParseException .

5. Conclusion

Dans ce didacticiel, nous avons expliqué comment utiliser la classe DateTimeFormatter pour mettre en forme les dates et les heures. Nous avons utilisé des exemples de modèles réels qui surviennent souvent lorsque nous travaillons avec des instances de date-heure.

Nous pouvons en savoir plus sur l'API Java 8 Date / Time dans les tutoriels précédents. Comme toujours, le code source utilisé dans le didacticiel est disponible à l'adresse over sur GitHub.