2016-08-19 4 views
4

je essaie de pase la prochaine String à l'aide LocalDateTime, mais je reçois toujours de texte non trouvé erreur:Erreur java.time.format.DateTimeParseException: ne pouvait pas être analysé, texte non trouvé à l'index 10

Error java.time.format.DateTimeParseException: Text '2016-08-18 14:27:15.103+02' could not be parsed, unparsed text found at index 10 

Voici ma chaîne: convertDate: '18/08/2016 14: 27: 15.103 + 02'

Et mon code:

public static LocalDate conversorStringToLocalDateTime(String convertDate) throws ParseException { 
    LocalDate dateTime =LocalDate.parse(convertDate); 
    return dateTime; 
} 

Je suppose est pas trop c compliqué, acheter je ne suis pas capable de voir l'erreur. Est-ce que le +02 dans la chaîne peut être la cause?

+0

Je pense que c'est l'espace entre la date et l'heure. Est-ce un char de l'espace ou un espace insécable? Si votre chaîne provient d'une forme quelconque, cela peut être un char différent d'un espace –

+0

Il provient d'une base de données Postgre –

Répondre

2

tl; dr

OffsetDateTime odt = OffsetDateTime.parse ("2016-08-18 14:27:15.103+02" , DateTimeFormatter.ofPattern ("yyyy-MM-dd HH:mm:ss.SSSX")) ; 

Détails

Le Answer by greg-449 est correct sur le problème (en utilisant un objet date uniquement pour une valeur date-heure) mais pas la solution .

Cette réponse utilise LocalDateTime ce qui jette inutilement des informations précieuses sur le offset-from-UTC. Un LocalDateTime ne pas représentent un moment spécifique sur la ligne de temps, seulement une idée vague sur les moments possibles en fonction de l'ajustement dans un fuseau horaire particulier. Le +02 est un offset-from-UTC signifiant "deux heures d'avance sur UTC". Donc, en UTC, l'heure du jour pour ce moment simultané est de 12 heures, 2 heures de moins que vos 14 heures. Ce représente un moment spécifique sur la timeline. Ce décalage est l'information précieuse que vous jetez avec un LocalDateTime plutôt qu'un OffsetDateTime.

Le format de votre chaîne est au format SQL, proche du format ISO 8601 standard. Remplacer simplement l'espace au milieu avec un T. Les classes java.time utilisent par défaut les formats ISO 8601, il n'est donc pas nécessaire de spécifier un formatage.

String input = "2016-08-18 14:27:15.103+02"; 
String inputModified = input.replace (" " , "T"); 

Malheureusement, Java 8 a un bogue dans l'analyse des valeurs de décalage en abrégé seulement une heure ou valeurs de décalage entre les deux points en omettant heures et minutes. Correction en Java 9. Mais en Java 8, nous devons ajuster l'entrée.

// Workaround for Java 8 where 2-digit offset fails parsing. Fixed in Java 9. 
int lengthOfAbbreviatedOffset = 3; 
if (inputModified.indexOf ("+") == (inputModified.length() - lengthOfAbbreviatedOffset)) { 
    // If third character from end is a PLUS SIGN, append ':00'. 
    inputModified = inputModified + ":00"; 
} 
if (inputModified.indexOf ("-") == (inputModified.length() - lengthOfAbbreviatedOffset)) { 
    // If third character from end is a PLUS SIGN, append ':00'. 
    inputModified = inputModified + ":00"; 
} 

Maintenant analyser.

OffsetDateTime odt = OffsetDateTime.parse (inputModified); 

Dump vers la console.Notez comment nous avons transformé +02 en +02:00.

System.out.println ("input: " + input + " | inputModified: " + inputModified + " | odt: " + odt); 

input: 2016-08-18 14:27:15.103+02 | inputModified: 2016-08-18T14:27:15.103+02:00 | odt: 2016-08-18T14:27:15.103+02:00

Vous pouvez également spécifier un modèle de mise en forme. Le bogue d'analyse de décalage ne mord pas lorsque vous utilisez ce modèle de mise en forme.

DateTimeFormatter f = DateTimeFormatter.ofPattern ("yyyy-MM-dd HH:mm:ss.SSSX"); 
    OffsetDateTime odt = OffsetDateTime.parse (input , f); 

Database

En venant de Postgres, vous devez récupérer la valeur en tant qu'objet date-heure plutôt que d'une chaîne. Si votre pilote JDBC est conforme à JDBC 4.2, vous pouvez appeler ResultSet::getObject pour obtenir un Instant ou OffsetDateTime. Si ce n'est pas le cas, appelez le ResultSet::getTimestamp pour obtenir un java.sql.Timestamp, puis convertissez immédiatement en java.time en appelant le toInstant sur l'objet Horodatage.

Stick avec java.time pour votre logique métier; utilisez les types java.sql brièvement et uniquement pour l'échange avec la base de données.

5

Votre code utilise LocalDate qui ne fait qu'analyser une date - pas une date et une heure de sorte que vous obtenez une erreur lorsque l'analyse trouve l'espace après la date.

Vous devriez donc utiliser LocalDateTime mais LocalDateTime.parse(String) attend une date au format ISO qui n'est pas le format que vous utilisez.

Vous devez donc utiliser un DateTimeFormatter pour spécifier le format de votre chaîne d'entrée. Quelque chose comme:

DateTimeFormatter format = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSX"); 
LocalDateTime result = LocalDateTime.parse(convertDate, format); 
+0

Oui !!! Ça a marché!!! J'avais déjà essayé d'utiliser LocalDateTime auparavant, mais avec le DateTimeFormatter usé. Merci :) –