2017-10-18 30 views
-2

Je souhaite utiliser DateTimeFormatter.ISO_LOCAL_DATE pour imprimer et analyser les dates. Voilà ce que je fais pour l'impression:Comment imprimer une date à l'aide de DateTimeFormatter.ISO_LOCAL_DATE?

Date date; 
String text = DateTimeFormatter.ISO_LOCAL_DATE.format(
    date.toInstant() 
); 

C'est ce que je reçois:

java.time.temporal.UnsupportedTemporalTypeException: Unsupported field: Year 
    at java.time.Instant.getLong(Instant.java:603) 
    at java.time.format.DateTimePrintContext$1.getLong(DateTimePrintContext.java:205) 
    at java.time.format.DateTimePrintContext.getValue(DateTimePrintContext.java:298) 
    at java.time.format.DateTimeFormatterBuilder$NumberPrinterParser.format(DateTimeFormatterBuilder.java:2543) 
    at java.time.format.DateTimeFormatterBuilder$CompositePrinterParser.format(DateTimeFormatterBuilder.java:2182) 
    at java.time.format.DateTimeFormatter.formatTo(DateTimeFormatter.java:1744) 
    at java.time.format.DateTimeFormatter.format(DateTimeFormatter.java:1718) 
+1

cela a fonctionné pour moi – Jerry06

+0

Fonctionne bien ici Java 1.8 – MadProgrammer

+0

mon mauvais, mis à jour la question, il était l'impression, pas l'analyse – yegor256

Répondre

0

Voilà comment cela fonctionne:

String text = DateTimeFormatter.ISO_LOCAL_DATE 
    .withZone(ZoneId.of("UTC")) 
    .format(date.toInstant()); 
+2

Au lieu de 'ZoneId.of (" UTC ")', vous pouvez également utiliser la constante intégrée 'ZoneOffset.UTC'. Selon [javadoc] (https://docs.oracle.com/javase/8/docs/api/java/time/ZoneId.html#of-java.lang.String-), ils sont équivalents: * "Si l'ID de zone est égal à 'GMT', 'UTC' ou 'UT', le résultat est un ZoneId avec le même identifiant et les mêmes règles que ZoneOffset.UTC "* –

1

Cela se produit parce que le Instant classe représente un point dans la chronologie: le nombre de nanosecondes depuis unix époque (1970-01-01T00:00Z), sans aucun concept de fuseau horaire - donc il n'a pas de date/heure spécifique (jour/mois/année, heures/min utes/secondes), car il peut représenter une date et une heure différentes dans différents fuseaux horaires.

Définition d'une zone spécifique dans le formatter, like you did, convertit le Instant à cette zone (de sorte que le nombre de nanosecondes depuis l'époque peut être traduit à une date et une heure), permettant de formater.

Pour ce cas précis, vous voulez que la partie date (jour, mois et année) ISO8601 format, donc une autre solution consiste à convertir le Instant à un LocalDate et appeler la méthode toString(). Lorsque vous définissez UTC dans le formatter, j'utilise le même pour le convertir:

String text = date.toInstant() 
    // convert to UTC 
    .atZone(ZoneOffset.UTC) 
    // get the date part 
    .toLocalDate() 
    // toString() returns the date in ISO8601 format 
    .toString(); 

Ce retour la même chose que your formatter. Bien sûr, pour d'autres formats, vous devez utiliser le formateur, mais spécifiquement pour ISO8601, vous pouvez utiliser la méthode toString().


Vous pouvez également convertir le Instant au fuseau horaire que vous voulez (dans ce cas, à UTC) et le transmettre directement à la formatter:

String text = DateTimeFormatter.ISO_LOCAL_DATE.format(
    date.toInstant().atZone(ZoneOffset.UTC) 
); 

La seule différence est que, lorsque vous définissez la zone dans le formateur, la date est convertie dans cette zone lors du formatage (lorsque vous ne le définissez pas, la date n'est pas convertie).