Reputation: 9521
I'm trying to write a DateTimeFormatter
to parse the following format:
2020-05-29T07:51:33.106-07:00
I have looked at ISO_OFFSET_DATE_TIME
, but the problem is it does not contain milliseconds. So I decided to write on my own.
It is easy to do so without timezone:
public static void main (String[] args) throws java.lang.Exception {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS");
System.out.println(
LocalDateTime.parse("2020-05-29T07:51:33.106", formatter)
);
}
But when I tried to add a timezone in the format as
public static void main (String[] args) throws java.lang.Exception {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
System.out.println(
LocalDateTime.parse("2020-05-29T07:51:33.106-07:00", formatter)
);
}
It now fails with an exception that the timezone is unable to be parsed.
Exception in thread "main" java.time.format.DateTimeParseException: Text '2020-05-29T07:51:33.106-07:00' could not be parsed at index 23
at java.base/java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:2049)
at java.base/java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1951)
at java.base/java.time.LocalDateTime.parse(LocalDateTime.java:492)
at Ideone.main(Main.java:16)
How to parse a timezone in such a format?
Upvotes: 5
Views: 7656
Reputation: 338171
No need to define a formatter.
OffsetDateTime.parse( "2020-05-29T07:51:33.106-07:00" )
The Answer by Jim Garrison is correct. In addition, you are using the wrong class.
The LocalDateTime
class represents only a date with a time-of-day, nothing more. This class purposely lacks any concept of time zone or offset-from-UTC. As such, this class cannot represent a moment, is not a point on the timeline.
So, parsing a string with an offset, the -07:00
on the end, as a LocalDateTime
does not make sense. The valuable information of offset will be ignored, discarded.
Instead, parse as an OffsetDateTime
.
Bonus: Your entire formatter issue becomes moot. Your input string complies with the standard ISO 8601 format used by default in the OffsetDateTime
class when parsing/generating strings. No need for you to define any custom formatting pattern at all.
OffsetDateTime.parse( "2020-05-29T07:51:33.106-07:00" )
…and:
myOffsetDateTime.toString()
You said:
But when I tried to add a timezone
No, you added an offset-from-UTC, not a time zone, with your string -07:00
.
America/Edmonton
. A time zone has a history of the past, present,
and future changes to the offset in the wall-clock time used by the
people of a particular region.Upvotes: 6
Reputation: 86744
From the Javadoc (emphasis mine):
Offset Z: This formats the offset based on the number of pattern letters. One, two or three letters outputs the hour and minute, without a colon, such as '+0130'. The output will be '+0000' when the offset is zero. Four letters outputs the full form of localized offset, equivalent to four letters of Offset-O. The output will be the corresponding localized offset text if the offset is zero. Five letters outputs the hour, minute, with optional second if non-zero, with colon. It outputs 'Z' if the offset is zero. Six or more letters throws IllegalArgumentException.
Change the single Z
to ZZZZZ
.
Upvotes: 8