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.
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 –
Il provient d'une base de données Postgre –