androidiso8601datetime-parsingthreetenabp

DateTimeParseException at index 0 with ThreeTenABP


I'm trying to parse a time string with ThreeTenABP (because I have to support min SDK 19). I think the string is ISO 8601:

20200117T172638.000Z

I get the following exception:

org.threeten.bp.format.DateTimeParseException: Text '20200117T172638.000Z' could not be parsed at index 0

My code:

Instant instant = Instant.parse("20200117T172638.000Z");
long time = instant.getEpochSecond();

Any help appreciated. Thanks in advance.


Solution

  • This is a little bit tricky alright.

        DateTimeFormatter instantFormatter = DateTimeFormatter.ofPattern("uuuuMMdd'T'HHmmss.SSSX");
        String s = "20200117T172638.000Z";
        Instant instant = instantFormatter.parse(s, Instant.FROM);
        System.out.println(instant);
    

    Output from this snippet is

    2020-01-17T17:26:38Z

    Getting the seconds since the epoch out if the Instant works as in your question, so I am not repeating it.

    Use a formatter that describes the precise format of the input string. Since there is no Instant.parse method that accepts a DateTimeFormatter as second argument, we need to do the parsing the other way around, using the (generic) DateTimeFormatter.parse(CharSequence, TemporalQuery<T>) method. And we need to pass the query Instant.FROM to that method because the backport is developed for Java versions that haven’t got method references. (Using the native java.time from Java 8 and later we would instead use the method reference Instant::from).

    I know that your string is in ISO 8601 format. And I know that it is said that the java.time classes parse ISO 8601 format without any explicit formatter (I have myself written that many times on Stack Overflow already). It is not quite true: the classes of java.time parse the most common variants of ISO 8601 format without any explicit formatter. ISO 8601 comes with quite many freedoms of syntax, some that are always allowed and some that can optionally be agreed between parties exchanging ISO 8601 format. You have run into a variant that Instant.parse() doesn’t deal with, sorry.