web-dev-qa-db-fra.com

java.time Modèle DateTimeFormatter pour le décalage de fuseau horaire

J'essaie d'analyser: 2014-05-02-10.45.05.993280-5:00 où le -5:00 est le décalage par rapport à l'UTC. Utilisation d'un Java.time DateTimeFormatter in Java 8.

Pour le premier bit, j'ai ce qui suit: yyyy-MM-dd-HH.mm.ss.SSSSSS cependant, je n'arrive pas à comprendre quel devrait être le motif pour analyser le décalage également.

Si j'avais l'offset à 4 chiffres (-05: 00) je pourrais utiliser: yyyy-MM-dd-HH.mm.ss.SSSSSSxxx, mais cela ne fonctionne pas pour 3 chiffres.

Des idées?

15
Cheetah

Utilisez la lettre majuscule X au lieu de x, d'où XXX. La différence est que le grand X peut reconnaître la lettre d'entrée "Z" comme UTC-Offset +00: 00 alors que la petite lettre de modèle X ne peut pas.

Modèle suggéré:

yyyy-MM-dd-HH.mm.ss.SSSSSSXXX

S'il vous plaît soyez également conscient de ce qui suit JDK-bug :

Java.time.format.DateTimeFormatter ne peut pas analyser un décalage avec une heure à un chiffre

MISE À JOUR:

J'ai maintenant testé la solution de contournement décrite dans le journal des bogues.

String input = "2014-05-02-10.45.05.993280-5:00";
DateTimeFormatter f = new DateTimeFormatterBuilder().appendPattern("yyyy-MM-dd-HH.mm.ss.SSSSSS").parseLenient().appendOffset("+HH:MM", "Z").toFormatter();
System.out.println(f.parse(input, ZonedDateTime::from));

Mais cela lève une exception:

Exception dans le thread "principal" Java.time.format.DateTimeParseException: le texte '2014-05-02-10.45.05.993280-5: 00' n'a pas pu être analysé à l'index 26 à Java.time.format.DateTimeFormatter.parseResolved0 (DateTimeFormatter. Java: 1947) sur Java.time.format.DateTimeFormatter.parse (DateTimeFormatter.Java:1849) sur HelloWorld.main (HelloWorld.Java:16)

L'analyse syntaxique indulgente n'aide pas non plus. Il ne vous reste donc plus que trois options:

  • Utilisez la solution de contournement suggérée par le rapporteur de bogues: [...] la solution consiste à analyser la date/l'heure séparément, à utiliser un analyseur codé à la main pour le décalage et à combiner LocalDateTime avec le décalage analysé à la main. Pas facile à contourner.

  • Essayez votre propre prétraitement de chaînes spécialisé. Si vous avez un format fixe, vous pouvez essayer d'insérer le chiffre zéro à la position 26 (si la longueur totale d'entrée est un chiffre trop petit).

  • Ou vous utilisez une bibliothèque externe qui peut le faire. Ma bibliothèque Time4J (v4.0) peut le faire si vous êtes prêt à ajouter une dépendance supplémentaire. Voir ce code:

String input = "2014-05-02-10.45.05.993280-5:00"; ZonalDateTime zdt = ZonalDateTime.parse( input, Moment.localFormatter("yyyy-MM-dd-HH.mm.ss.SSSSSSXXX", PatternType.CLDR)); System.out.println(zdt); // 2014-05-02T10:45:05,993280UTC-05:00 ZonedDateTime result = zdt.toTemporalAccessor();

Mise à jour: Selon JDK-bug-status, le bogue a été corrigé pour Java-9, mais un backport pour Java-8 ne semble pas être disponible cependant.

17
Meno Hochschild

Le décalage pour le signe SimpleDateFormat est Z cocher Java7 ou Java8SimpleDateFormat API.

Ensuite, votre format d'analyseur pour String

2014-05-02-10.45.05.993280-5:00

doit être:

yyyy-MM-dd-HH.mm.ss.SSSSSSZ

[~ # ~] mise à jour [~ # ~] : pour DateTimeFormatter l'offset Modèles pour Le formatage et l'analyse sont:

O       localized zone-offset       offset-O          GMT+8; GMT+08:00; UTC-08:00;
X       zone-offset 'Z' for zero    offset-X          Z; -08; -0830; -08:30; -083015; -08:30:15;
x       zone-offset                 offset-x          +0000; -08; -0830; -08:30; -083015; -08:30:15;
Z       zone-offset                 offset-Z          +0000; -0800; -08:00;

Votre modèle souhaité dans DateTimeFormatter est X.

3
Jordi Castilla