web-dev-qa-db-fra.com

java.time.format.DateTimeParseException: le texte n'a pas pu être analysé à l'index 21

Je reçois la valeur datetime comme

created_at  '2012-02-22T02:06:58.147Z'
Read-only. The time at which this task was created.

Qui est donné par Asana (~ ~ ~ ~] api [~ # ~]

J'utilise Java 8 pour analyser la date et l'heure comme suit

import Java.time.*;
import Java.time.format.*;

public class Times {

  public static void main(String[] args) {
    final String dateTime = "2012-02-22T02:06:58.147Z";
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'hh:mm:ss.SX");


    final ZonedDateTime parsed = ZonedDateTime.parse(dateTime, formatter);
    System.out.println(parsed);
  }
}

Quand j'exécute ceci, j'obtiens l'erreur suivante

Exception in thread "main" Java.time.format.DateTimeParseException: Text '2012-02-22T02:06:58.147Z' could not be parsed at index 21
    at Java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.Java:1947)
    at Java.time.format.DateTimeFormatter.parse(DateTimeFormatter.Java:1849)
    at Java.time.ZonedDateTime.parse(ZonedDateTime.Java:597)
    at Times.main(Times.Java:11)
    at Sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at Sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.Java:62)
    at Sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.Java:43)
    at Java.lang.reflect.Method.invoke(Method.Java:497)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.Java:140)

Qu'est-ce qui ne va pas ici?

21
daydreamer

L'analyseur par défaut peut analyser votre entrée. Donc, vous n'avez pas besoin d'un formateur personnalisé et

String dateTime = "2012-02-22T02:06:58.147Z";
ZonedDateTime d = ZonedDateTime.parse(dateTime);

fonctionne comme prévu.

19
assylias

Si votre entrée a toujours un fuseau horaire "zulu" ("Z" = UTC), vous pouvez utiliser DateTimeFormatter.ISO_INSTANT (implicitement):

final Instant parsed = Instant.parse(dateTime);

Si le fuseau horaire varie et prend la forme "+01: 00" ou "+01: 00: 00" (sinon "Z"), vous pouvez utiliser DateTimeFormatter.ISO_OFFSET_DATE_TIME:

DateTimeFormatter formatter = DateTimeFormatter.ISO_OFFSET_DATE_TIME;
final ZonedDateTime parsed = ZonedDateTime.parse(dateTime, formatter);

Si ce n'est pas le cas, vous pouvez construire un DateTimeFormatter de la même manière que DateTimeFormatter.ISO_OFFSET_DATE_TIME est construit.


Votre modèle actuel a plusieurs problèmes:

  • ne pas utiliser le mode strict (ResolverStyle.STRICT);
  • utiliser yyyy au lieu de uuuu (yyyy ne fonctionnera pas en mode strict);
  • en utilisant 12 heures hh au lieu de 24 heures HH;
  • en utilisant un seul chiffre S pendant une fraction de seconde, mais l’entrée en a trois.
19
Roman

Votre problème initial était le symbole de configuration incorrect "h" qui correspond à l'heure de l'horloge (plage 1-12). Dans ce cas, les informations am-pm sont manquantes. Mieux, utilisez le symbole de motif "H" à la place (heure du jour comprise entre 0 et 23). Donc, le motif aurait plutôt dû être comme:

uuuu-MM-dd'T'HH: mm: ss.SSSX (meilleur modèle également adapté au mode strict)

2
Meno Hochschild

Ce qui suit a fonctionné pour moi

import Java.time.*;
import Java.time.format.*;

public class Times {

  public static void main(String[] args) {
    final String dateTime = "2012-02-22T02:06:58.147Z";
    DateTimeFormatter formatter = DateTimeFormatter.ISO_INSTANT;
    final ZonedDateTime parsed = ZonedDateTime.parse(dateTime, formatter.withZone(ZoneId.of("UTC")));
    System.out.println(parsed.toLocalDateTime());
  }
}

et m'a donné la sortie en tant que

2012-02-22T02:06:58.147
1
daydreamer