2016-08-19 2 views
4
gefunden

Ich versuche das nächste String mit Local PASE, aber ich bekomme immer de unparsed Text Fehler gefunden:Fehler java.time.format.DateTimeParseException: konnte nicht analysiert werden, unparsed Text im 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 

Hier ist mein String: convertDate: '2016.08.18 14: 27: 15.103 + 02'

Und mein Code:

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

ich denke, nicht zu ist c omplicated, buy Ich kann den Fehler nicht sehen. Könnte die +02 im String die Ursache sein?

+0

Ich denke, ist der Abstand zwischen dem Datum und der Uhrzeit. Ist das ein Space-Char oder ein brechungsfreier Raum? Wenn Ihre Zeichenfolge aus einem Formular irgendeiner Art stammt, kann das ein anderes Zeichen als ein Leerzeichen sein –

+0

Es stammt aus einer Postgre-Datenbank –

Antwort

2

tl; dr

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

Einzelheiten

Die Answer by greg-449 korrekt über das Problem (mit einem Nur-Datum-Objekt für ein Datum-Zeit-Wert), aber nicht die Lösung .

Diese Antwort verwendet LocalDateTime, die unnötig wertvolle Informationen über die offset-from-UTC wegwirft. A LocalDateTime does nicht repräsentieren einen bestimmten Moment auf der Timeline, nur eine vage Vorstellung über mögliche Momente abhängig von der Anpassung in einer bestimmten Zeitzone. Die +02 ist eine offset-from-UTC Bedeutung "zwei Stunden vor UTC". In UTC beträgt die Uhrzeit für diesen simultanen Moment also 12 Stunden, also 2 Stunden weniger als 14 Stunden. Diese stellt einen bestimmten Moment auf der Timeline dar. Dieser Offset ist die wertvolle Information, die Sie mit einem LocalDateTime eher als ein OffsetDateTime wegwerfen.

Das Format Ihrer Zeichenfolge ist im SQL-Format, das dem ISO 8601-Standardformat entspricht. Ersetzen Sie einfach den RAUM in der Mitte mit einem T. Die java.time-Klassen verwenden standardmäßig ISO 8601-Formate, sodass Sie kein Formatierungsmuster angeben müssen.

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

Leider hat Java 8 einen Fehler beim Parsen von Offset-Werten, abgekürzt auf nur eine Stunde oder Offset-Werte unter Auslassung des Doppelpunkts zwischen Stunden und Minuten. In Java 9 behoben. Aber in Java 8 müssen wir die Eingabe anpassen.

// 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"; 
} 

Jetzt analysieren.

OffsetDateTime odt = OffsetDateTime.parse (inputModified); 

Dump zur Konsole.Beachten Sie, wie wir +02 in +02:00 umgewandelt haben.

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

Alternativ ein Formatierungsmuster angeben. Der Offset-Parsing-Fehler beißt nicht, wenn dieses Formatierungsmuster verwendet wird.

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

Datenbank

von Postgres kommend, sollten Sie den Wert als Datetime-Objekt wurden Abrufen anstatt ein String.

Wenn Ihr JDBC-Treiber JDBC 4.2 entspricht, können Sie ResultSet::getObject anrufen, um eine Instant oder OffsetDateTime zu erhalten. Wenn nicht, rufen Sie ResultSet::getTimestamp an, um eine java.sql.Timestamp zu erhalten, und konvertieren Sie dann sofort in java.time, indem Sie toInstant auf dem Timestamp-Objekt aufrufen.

Bleiben Sie bei java.time für Ihre Geschäftslogik. Verwenden Sie die Typen java.sql kurz und nur für den Austausch mit der Datenbank.

5

Ihr Code verwendet LocalDate, die nur ein Datum analysiert - nicht ein Datum und eine Uhrzeit, so dass Sie einen Fehler erhalten, wenn die Analyse das Leerzeichen nach dem Datum findet.

Sie sollten also LocalDateTime verwenden, aber LocalDateTime.parse(String) erwartet ein ISO-Format Datum, das nicht das Format ist, das Sie verwenden.

Sie müssen also ein verwenden, um das Format Ihrer Eingabezeichenfolge anzugeben. Etwas wie:

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

Ja !!! Das hat funktioniert!!! Ich hatte vorher versucht, LocalDateTime zu benutzen, aber mit dem DateTimeFormatter. Danke :) –

Verwandte Themen