java.time.format.DateTimeParseException: Text '2021-02-19T00:45:09.798Z' could not be parsed, unparsed text found at index 23

Viewed 3837

I'm new to java and I'm not understanding what's wrong with my date parsing. I've tried many of the solutions to similar posts, read the DateTimeFormatter documentation and am still stuck. Any help is appreciated. Thank you.

Code

String date = "2021-02-19T00:45:09.798Z"
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss.SSSZ");
ZonedDateTime parsedDate = ZonedDateTime.parse(date, formatter);

Error

java.time.format.DateTimeParseException: Text '2021-02-19T00:45:09.798Z' could not be parsed, unparsed text found at index 23

I've also tried using DateTimeFormatter.ofPattern(pattern).withZone(zone) and receive the same error.

2 Answers

You do not need a formatter to parse the given date-time string as it's already compliant with the default format that ZoneDateTime#parse expects.

import java.time.ZonedDateTime;

public class Main {
    public static void main(String[] args) {
        String date = "2021-02-19T00:45:09.798Z";
        ZonedDateTime parsedDate = ZonedDateTime.parse(date);
        System.out.println(parsedDate);
    }
}

Output:

2021-02-19T00:45:09.798Z

Learn more about the modern date-time API from Trail: Date Time.


* For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.

Index 23 of your input is Z, the time offset indicator. And indeed, if we look at the formatting patterns docs, we see the "Z" as a pattern for offsets with:

Offset Z: [...] 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.

, and "X" as a pattern for offsets while using 'Z' for zero:

Offset X: [...] Pattern letter 'X' (upper case) will output 'Z' when the offset to be output would be zero . Therefore, this works:

DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss.SSSX")

That said, if your input is in a well-known ISO 8601 standard format, you might want to use one of the predefined formatters instead, like ISO_OFFSET_DATE_TIME (or some other, depending on your input's ZoneId/offset usage).

Related