Home > Blockchain >  How to parse ISO date with microsecond precision in Kotlin
How to parse ISO date with microsecond precision in Kotlin

Time:12-30

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

CodePudding user response:

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

  • Related