I'm trying to move from Joda to Java 8's ZonedDateTime and I'm hitting a wall with the DateTimeFormatterBuilder that I cannot seem to work around.
I want to accept any of these formats:
2013-09-20T07:00:33
2013-09-20T07:00:33.123
2013-09-20T07:00:33.123+0000
2013-09-20T07:00:33.123Z
2013-09-20T07:00:33.123Z+0000
2013-09-20T07:00:33+0000
Here is my current builder:
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.parseCaseInsensitive()
.append(DateTimeFormatter.ISO_LOCAL_DATE_TIME)
.optionalStart()
.appendPattern(".SSS")
.optionalEnd()
.optionalStart()
.appendZoneId()
.optionalEnd()
.optionalStart()
.appendPattern("Z")
.optionalEnd()
.toFormatter();
I'm probably wrong, but it appears that should match the patterns I want... right?
If anyone could point of what I may have missed, it'd be appreciated. I'm also not too sure of the use of appendOffset, so clarity on that is also appreciated if it turns out to be the answer.
Edit:
Text '2013-09-20T07:00:33.061+0000' could not be parsed at index 23
Looking at the builder, this appears to match due to the optional stages?
Edit 2:
After seeing advice from the first answer, I tried this:
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.parseCaseInsensitive()
.append(DateTimeFormatter.ISO_LOCAL_DATE_TIME)
.optionalStart()
.appendPattern(".SSS")
.optionalEnd()
.optionalStart()
.appendZoneOrOffsetId()
.optionalEnd()
.toFormatter()
It continues to fail on the string above.
Edit 3:
Latest tests result in this exception:
java.time.format.DateTimeParseException: Text '2013-09-20T07:00:33.061+0000' could not be parsed at index 23
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 java.time.ZonedDateTime.parse(ZonedDateTime.java:582)
Represents a time (hour, minute, second and nanoseconds (HH-mm-ss-ns)) LocalDateTime. Represents both a date and a time (yyyy-MM-dd-HH-mm-ss-ns) DateTimeFormatter. Formatter for displaying and parsing date-time objects.
public final class DateTimeFormatter extends Object. Formatter for printing and parsing date-time objects. This class provides the main application entry point for printing and parsing and provides common implementations of DateTimeFormatter : Using predefined constants, such as ISO_LOCAL_DATE.
Yes, it is: DateTimeFormat is thread-safe and immutable, and the formatters it returns are as well.
For time patterns, use mm for two-digit minute and ss for two-digit second. The hh pattern generates the two-digit hour for a 12-hour clock (e.g., 6PM is "06") and HH generates the two-digit hour for a 24-hour clock (e.g., 6PM is "18").
It may be the reason that +0000 is not a zone id, but a zone offset.
the documentation offers this list:
Symbol Meaning Presentation Examples
------ ------- ------------ -------
V time-zone ID zone-id America/Los_Angeles; Z; -08:30
z time-zone name zone-name Pacific Standard Time; PST
O localized zone-offset offset-O GMT+8; GMT+08:00; UTC-08:00;
X zone-offset 'Z' for zero offset-X Z; -08; -0830; -08:30; -083015; -08:30:15;
x zone-offset offset-x +0000; -08; -0830; -08:30; -083015; -08:30:15;
Z zone-offset offset-Z +0000; -0800; -08:00;
You may use appendOffset("+HHMM", "0000") (doc) or appendZoneOrOffsetId() (doc) instead of appendZoneId().
so your full formatter may look like the following
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.parseCaseInsensitive()
.append(DateTimeFormatter.ISO_LOCAL_DATE_TIME)
.optionalStart()
.appendPattern(".SSS")
.optionalEnd()
.optionalStart()
.appendZoneOrOffsetId()
.optionalEnd()
.optionalStart()
.appendOffset("+HHMM", "0000")
.optionalEnd()
.toFormatter();
Further the way of creating a ZonedDateTime may influence if there is an exception or not. Therefore I'd recommend the following as this worked without any exceptions.
LocalDateTime time = LocalDateTime.parse("2013-09-20T07:00:33.123+0000", formatter);
ZonedDateTime zonedTime = time.atZone(ZoneId.systemDefault());
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With