2

I got this from https://stackoverflow.com/a/18217193/6727914

val df1: DateFormat = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ")
val string1 = "2022-12-29T19:59:20.783357Z"
val result1: Date = df1.parse(string1)

But it does not work:

Exception in thread "main" java.text.ParseException: Unparseable date: "2022-12-29T19:59:20.783357Z" at java.text.DateFormat.parse (:-1)
at FileKt.main (File.kt:13) at FileKt.main (File.kt:-1)

I can't use Instant.parse(date)

The date "2022-12-29T19:59:20.783357Z" is a valid Iso8601String where 783 is the milliseconds and 357 is the micro seconds

10
  • 1
    It doesn't match the format you provide; it's not clear what you expect. S is for milliseconds, there's 1000 of them per second, and 783357 > 1000. Commented Dec 29, 2022 at 20:07
  • Did you consider looking at api.flutter.dev/flutter/dart-core/DateTime/parse.html? It's not clear why this is tagged Java/Kotlin if you're using Dart references :shrug: Commented Dec 29, 2022 at 20:12
  • @DaveNewton The questions title is how to parse ISO date in kotlin, the expectation is thus having the date parsed. The date provided is a valid ISO date, not sure what is not clear Commented Dec 29, 2022 at 20:13
  • The biggest point of misclarity is why microseconds are included in your string, but completely absent from the format string (I don't know if SDF handles microseconds, but the format string ignores them, hence the error). Commented Dec 29, 2022 at 20:15
  • 1
    I can't use Instant.parse(date) Why not? SimpleDateFormat does not offer microsecond precision. Commented Dec 29, 2022 at 20:15

1 Answer 1

3

SimpleDateFormat can not handle fraction-of-second up to microseconds resolution, its limit is up to millisecond resolution. If you try to parse it as it is, you will get the wrong result as explained in this answer.

You have two choices:

  1. Truncate fraction of second up to milliseconds resolution.
  2. Use ThreeTenABP or Android desugaring support as explained in this post. You can then use Instant#parse to parse your date-time string into an Instant.

Note: You need to use X instead of Z in your pattern.

Demo:

import java.text.ParseException;
import java.text.SimpleDateFormat;

public class Main {
    public static void main(String[] args) throws ParseException {
        var df1 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSX");
        var string1 = "2022-12-29T19:59:20.783357Z";
        string1 = string1.replaceAll("(\\.\\d{3})\\d+", "$1");
        var result1 = df1.parse(string1);
        System.out.println(result1);
    }
}

Output in my time zone, Europe/London:

Thu Dec 29 19:59:20 GMT 2022

Solution using java.time API

import java.time.Instant;
import java.util.Date;

public class Main {
    public static void main(String[] args) {
        var instant = Instant.parse("2022-12-29T19:59:20.783357Z");
        System.out.println(instant);

        // For any reason, if you need java.util.Date
        var date = Date.from(instant);
        System.out.println(date);
    }
}

ONLINE DEMO

Sign up to request clarification or add additional context in comments.

1 Comment

The recommended java.time solution is available for API level 21 through desugaring.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.