Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ISO 8601 with milliseconds and Retrofit

I cannot set properly the date format when using retrofit and trying to read a date like this:

2015-08-29T11:22:09.815479Z

An the GSON converter I'm setting is like this:

GsonConverter gsonConverter = new GsonConverter(
     new GsonBuilder()
            .setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSSSSz")
            .create()
);

Any clues on what's the problem?

like image 213
Javier Manzano Avatar asked Aug 29 '15 11:08

Javier Manzano


People also ask

Does ISO 8601 include milliseconds?

ISO 8601 represents date and time by starting with the year, followed by the month, the day, the hour, the minutes, seconds and milliseconds. For example, 2020-07-10 15:00:00.000, represents the 10th of July 2020 at 3 p.m. (in local time as there is no time zone offset specified—more on that below).

Does ISO 8601 support nanoseconds?

Everything related to datetimes is handled through the rust-chrono package, which is precise to the nanosecond and can parse ISO 8601 formatted strings, truncating digits more granular than nanoseconds.

Is ISO 8601 always UTC?

The toISOString() method returns a string in ISO format (ISO 8601 Extended Format), which can be described as follows: YYYY-MM-DDTHH:mm:ss. sssZ . The timezone is always UTC as denoted by the suffix "Z".


2 Answers

Java 8 Instant class can be used to easily parse ISO-8601 timestamps without explicitly setting a format string, for example:

String input = "2018-11-07T00:25:00.073876Z";
Instant instant = Instant.parse(input);
like image 142
AmitW Avatar answered Sep 21 '22 17:09

AmitW


Java Date has millisecond precision so I've been creating the Gson object like so:

Gson gson = new GsonBuilder()
        .setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")
        .create();

Of course, in a case like this, the microseconds are being truncated whether you put SSS or SSSSSS. It is also assumed that the last character of the converted string is always a Z.

To explain why your pattern didn't work, you used z (lowercase z) which according to the documentation represents a General Timezone (e.g., Pacific Standard Time; PST; GMT-08:00). Additionally, if you were to use Z (uppercase Z), it would also not work since it represents an RFC 822 time zone (e.g., -0800).

In another scenario where instead of the Z you have a time zone offset (e.g., -08, -0800, or -08:00), you can use X, XX, or XXX to represent an ISO 8610 time zone. But that requires Java 7 or 8 (I don't think Android is compatible with Java 8 at the moment).


Another method would be to write your own Gson Serializer and Deserializer; although I haven't tried.

It's also worth looking at java.sql.Timestamp class which is also supported by Gson and has more fine grained precision (nanoseconds) but it's also an option I haven't explored.

like image 44
grim Avatar answered Sep 19 '22 17:09

grim