java.time.format.DateTimeParseException: Text could not be parsed at index 21
Solution 1
The default parser can parse your input. So you don't need a custom formatter and
String dateTime = "2012-02-22T02:06:58.147Z";
ZonedDateTime d = ZonedDateTime.parse(dateTime);
works as expected.
Solution 2
If your input always has a time zone of "zulu" ("Z" = UTC), then you can use DateTimeFormatter.ISO_INSTANT
(implicitly):
final Instant parsed = Instant.parse(dateTime);
If time zone varies and has the form of "+01:00" or "+01:00:00" (when not "Z"), then you can use DateTimeFormatter.ISO_OFFSET_DATE_TIME
:
DateTimeFormatter formatter = DateTimeFormatter.ISO_OFFSET_DATE_TIME;
final ZonedDateTime parsed = ZonedDateTime.parse(dateTime, formatter);
If neither is the case, you can construct a DateTimeFormatter
in the same manner as DateTimeFormatter.ISO_OFFSET_DATE_TIME
is constructed.
Your current pattern has several problems:
- not using strict mode (
ResolverStyle.STRICT
); - using
yyyy
instead ofuuuu
(yyyy
will not work in strict mode); - using 12-hour
hh
instead of 24-hourHH
; - using only one digit
S
for fractional seconds, but input has three.
Solution 3
Your original problem was wrong pattern symbol "h" which stands for the clock hour (range 1-12). In this case, the am-pm-information is missing. Better, use the pattern symbol "H" instead (hour of day in range 0-23). So the pattern should rather have been like:
uuuu-MM-dd'T'HH:mm:ss.SSSX (best pattern also suitable for strict mode)
Solution 4
The following worked for me
import java.time.*;
import java.time.format.*;
public class Times {
public static void main(String[] args) {
final String dateTime = "2012-02-22T02:06:58.147Z";
DateTimeFormatter formatter = DateTimeFormatter.ISO_INSTANT;
final ZonedDateTime parsed = ZonedDateTime.parse(dateTime, formatter.withZone(ZoneId.of("UTC")));
System.out.println(parsed.toLocalDateTime());
}
}
and gave me output as
2012-02-22T02:06:58.147
daydreamer
Hello Viewer, Some of the places to see my work are BonsaiiLabs My Website
Updated on March 09, 2020Comments
-
daydreamer about 4 years
I get the datetime value as
created_at '2012-02-22T02:06:58.147Z' Read-only. The time at which this task was created.
Which is given by Asana API
I am using
Java 8
to parse the date time as followingimport java.time.*; import java.time.format.*; public class Times { public static void main(String[] args) { final String dateTime = "2012-02-22T02:06:58.147Z"; DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'hh:mm:ss.SX"); final ZonedDateTime parsed = ZonedDateTime.parse(dateTime, formatter); System.out.println(parsed); } }
When I run this, I get the following error
Exception in thread "main" java.time.format.DateTimeParseException: Text '2012-02-22T02:06:58.147Z' could not be parsed at index 21 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 Times.main(Times.java:11) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:497) at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)
What is not right here?
-
Meno Hochschild about 8 yearsGood observation regarding strict or lenient mode! I had originally assumed lenient mode in my answer. For information: Pattern with only one S-symbol instead of ".SSS" is okay in lenient mode.
-
UserBSS1 almost 3 yearsSaved by "format "+01:00" or "+01:00:00" (when not "Z"), then you can use DateTimeFormatter.ISO_OFFSET_DATE_TIME"