Reputation: 201
I am trying to parse an input string to local date time.
Below is my piece of code
ZonedDateTime z = ZonedDateTime.parse("2019-11-26T19:30:00Z", MY_DATE_TIME_FORMATTER);
where
MY_DATE_TIME_FORMATTER= new DateTimeFormatterBuilder()
.parseCaseInsensitive()
.append(ISO_LOCAL_DATE)
.appendLiteral('T')
.append(ISO_LOCAL_TIME)
.appendLiteral('Z')
.appendOffset("+HH:mm", "+0000")
.toFormatter();
I get the following exception
java.time.format.DateTimeParseException: Text '2019-11-26T19:30:00Z' could not be parsed at index 19
Can you please advise on what I am doing wrong here?
Upvotes: 3
Views: 165
Reputation: 338496
Instant.parse
No formatting pattern needed.
Instant.parse( "2019-11-26T19:30:00Z" )
Your input format complies with ISO 8601 standard. That particular format has a Z
on the end. That letter means UTC (an offset of zero hours-minutes-seconds), and is pronounced “Zulu”.
The Instant
class in java.time represents a moment in UTC, always UTC.
Using ZonedDateTime
class for that input is not the most appropriate. We have:
Instant
for values that are always in UTC.OffsetDateTime
for moments where only an offset-from-UTC is known but not a time zone. Use this class for UTC values too when you need more flexibility such as generating strings in various formats. `instant.atOffset(ZonedDateTime
for values in a time zone. A time zone is a history of past, present, and future changes to the offset used by the people of a particular region.To view that same moment adjusted to the offset used by the people of a particular region (a time zone), apply a ZoneId
to get a ZonedDateTime
object.
Instant instant = Instant.parse( "2019-11-26T19:30:00Z" ) ; // Default format for parsing a moment in UTC.
ZoneId z = ZoneId.of( "America/Edmonton" ) ; // A time zone is a history of past, present, and future changes to the offset used by the people of a particular region.
ZonedDateTime zdt = instant.atZone( z ) ; // Same moment, same point on the timeline, different wall-clock time.
See this code run live at IdeOne.com.
instant.toString(): 2019-11-26T19:30:00Z
zdt.toString(): 2019-11-26T12:30-07:00[America/Edmonton]
Upvotes: 3
Reputation: 7279
Add
.appendZoneOrOffsetId()
instead of these two lines:
.appendLiteral('Z')
.appendOffset("+HH:mm", "+0000")
The whole builder example:
MY_DATE_TIME_FORMATTER= new DateTimeFormatterBuilder()
.parseCaseInsensitive()
.append(ISO_LOCAL_DATE)
.appendLiteral('T')
.append(ISO_LOCAL_TIME)
.appendZoneOrOffsetId()
.toFormatter();
P.S. In your specific case I'd rather use the standard ISO formatter (as Hristo mentioned):
ZonedDateTime z = ZonedDateTime.parse("2019-11-26T19:30:00Z", DateTimeFormatter.ISO_ZONED_DATE_TIME);
Moreover, the ZonedDateTime::parse
method will work even without the explicit formatter. Since it's used by default:
ZonedDateTime z = ZonedDateTime.parse("2019-11-26T19:30:00Z");
Upvotes: 1
Reputation: 1049
Use the built in ISO zoned time formatter
ZonedDateTime.parse("2019-11-26T19:30:00Z", DateTimeFormatter.ISO_ZONED_DATE_TIME);
Upvotes: 0