Moin,
folgendes Problem: Aus einem String mit ISO 8601 Datum und Zeit ein java.util.Date machen.
Schwierigkeit: String kann mit oder ohne Zeitzone / Offset sein. Ich will also eine Zeitzone
vorgeben können, wenn im String keine vorhanden ist.
Erster Versuch war mit DateTimeFormatter.ISO_OFFSET_DATE_TIME, der wirft aber eine Exception
wenn der Offset keinen Doppelpunkt enthält.
Also versucht selbst einen DateTimeFormatter zu bauen.
import java.sql.Date;
import java.time.OffsetDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
public class IsoTimeTest {
public static void main(String[] args) {
parse(
"2015-01-28T16:59:58",
"2015-01-28T16:59:58.212",
"2015-01-28T16:59:58.212+0500",
"2015-01-28T16:59:58.212+05:00",
"2015-01-28T16:59:58.212+05",
"2015-01-28T16:59:58+05:00",
"2015-01-28T16:59:58+0500",
"2015-01-28T16:59:58+05"
);
}
public static void parse(String... dates) {
Arrays.stream(dates).forEach((d) -> {
System.out.print("Zoned ");
IsoTimeTest.parseWithZoned(d);
});
Arrays.stream(dates).forEach((d) -> {
System.out.print("Offset ");
IsoTimeTest.parseWithOffset(d);
});
}
public static void parseWithZoned(String date) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss[.SSS][XXX][XX][X]").withZone(ZoneId.of("Europe/Berlin"));
try {
ZonedDateTime zdt = ZonedDateTime.parse(date, formatter);
System.out.println("OK: " + date + " -- " + Date.from(zdt.toInstant()));
} catch (Exception e) {
System.out.println("NOK: " + date + " -- " + e.getMessage());
}
}
public static void parseWithOffset(String date) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss[.SSS][XXX][XX][X]").withZone(ZoneId.of("Europe/Berlin"));
try {
OffsetDateTime zdt = OffsetDateTime.parse(date, formatter);
System.out.println("OK: " + date + " -- " + Date.from(zdt.toInstant()));
} catch (Exception e) {
System.out.println("NOK: " + date + " -- " + e.getMessage());
}
}
}
Zoned OK: 2015-01-28T16:59:58 -- Wed Jan 28 16:59:58 CET 2015
Zoned OK: 2015-01-28T16:59:58.212 -- Wed Jan 28 16:59:58 CET 2015
Zoned OK: 2015-01-28T16:59:58.212+0500 -- Wed Jan 28 16:59:58 CET 2015
Zoned OK: 2015-01-28T16:59:58.212+05:00 -- Wed Jan 28 16:59:58 CET 2015
Zoned OK: 2015-01-28T16:59:58.212+05 -- Wed Jan 28 16:59:58 CET 2015
Zoned OK: 2015-01-28T16:59:58+05:00 -- Wed Jan 28 16:59:58 CET 2015
Zoned OK: 2015-01-28T16:59:58+0500 -- Wed Jan 28 16:59:58 CET 2015
Zoned OK: 2015-01-28T16:59:58+05 -- Wed Jan 28 16:59:58 CET 2015
Offset NOK: 2015-01-28T16:59:58 -- Text '2015-01-28T16:59:58' could not be parsed: Unable to obtain OffsetDateTime from TemporalAccessor: {InstantSeconds=1422460798},ISO,Europe/Berlin resolved to 2015-01-28T16:59:58 of type java.time.format.Parsed
Offset NOK: 2015-01-28T16:59:58.212 -- Text '2015-01-28T16:59:58.212' could not be parsed: Unable to obtain OffsetDateTime from TemporalAccessor: {InstantSeconds=1422460798},ISO,Europe/Berlin resolved to 2015-01-28T16:59:58.212 of type java.time.format.Parsed
Offset OK: 2015-01-28T16:59:58.212+0500 -- Wed Jan 28 12:59:58 CET 2015
Offset OK: 2015-01-28T16:59:58.212+05:00 -- Wed Jan 28 12:59:58 CET 2015
Offset OK: 2015-01-28T16:59:58.212+05 -- Wed Jan 28 12:59:58 CET 2015
Offset OK: 2015-01-28T16:59:58+05:00 -- Wed Jan 28 12:59:58 CET 2015
Offset OK: 2015-01-28T16:59:58+0500 -- Wed Jan 28 12:59:58 CET 2015
Offset OK: 2015-01-28T16:59:58+05 -- Wed Jan 28 12:59:58 CET 2015
Hmm, ZonedDateTime frisst zwar alles, aber der Offset wird einfach mal ignoriert, wenn vorhanden.
Das kommt mir völlig kaputt vor, warum sollte man jemals einen vorhandenen Offset überschreiben?.
Mit OffsetDateTime ist das Ergebnis noch absurder, er wirft eine Exception, obwohl er alle Infos
hat um den Offset berechnen zu können.
Macht das für irgendjemanden Sinn?