Moshi: Java 8 Date Api Type Adapters

Created on 25 Jul 2016  路  15Comments  路  Source: square/moshi

I was looking for LocalDate and LocalDateTime type adapters, but I didn't found them. Can you add it in future?

enhancement

Most helpful comment

Why has everybody write it's own adapters over and over again...?

There's no one standard way to serialize datetimes to JSON. JSON itself does not have a datetime type. I've seen them serialized as:

Picking just one of those is going to make everyone else upset. As Jake said, it's 4 simple lines of code to get exactly what you need.

On top of all this, java.time has many different classes (LocalDateTime, Instant, ZonedDateTime for example) that would need to be supported.

All 15 comments

You can probably build adapters using @ToJson and @FromJson pretty easily as long as you also use our java.util.Date adapter.

I have already done it pretty easily. However I think this should be included in library.

```
import com.squareup.moshi.JsonAdapter;
import com.squareup.moshi.JsonReader;
import com.squareup.moshi.JsonWriter;
import java.io.IOException;
import java.time.Duration;

public final class IsoDurationJsonAdapter extends JsonAdapter {
@Override public synchronized Duration fromJson(JsonReader reader) throws IOException {
String string = reader.nextString();
return Duration.parse(string);
}

@Override public synchronized void toJson(JsonWriter writer, Duration value) throws IOException {
    String string = (value == null) ? null : value.toString();
    writer.value(string);
}

}
`

Another useful one...

You don't need to take JsonReader or JsonWriter there. Just accept String and return String.

Also drop synchronized. java.time APIs are thread-safe unless otherwise noted (these are safe).

The String methods of the JsonAdapter are final unfortunately :-(
Removed synchronized...thanks. That was from an autoconversion to Kotlin by Android Studio :-)

`
public final @Nullable T fromJson(String string) throws IOException

public final String toJson(@Nullable T value)

`

Jake meant with @FromJson and @ToJson methods, you can accept and return a String delegate.
like @FromJson Duration fromJson(String string) {...} @ToJson String toJson(Duration duration) {...}

less code than writing a full JsonAdapter manually.

:+1: I'd definitely appreciate if this made it into the library

Still not made it to the library? :(

Can't believe that Moshi still doesn't provide build-in support f眉r JSR-310 time formats / ISO 8601. Why has everybody write it's own adapters over and over again...?

Because it's ~4 lines of code and allows infinite customization without the need to try and accommodate all the knobs user's want. Moshi is small by design and empowers you to easily compose such functionality yourself.

If you have no intention to include the adapters into the library, then say that and close the issue. I could totally understand if you believe that those adapters are a bad fit for a small-by-design library. Otherwise, the same applies to you: Its just ~4 lines of code that could've easily been added to the library in the 4 years this issue exists.

Actually no. It doesn't apply to us. We have to design the adapter in a way that can be used by everyone and everyone's requirements are different than yours. It's far more likely such adapters would require 100 lines of code for us to offer compared to the 4 which you need. Not to mention the extensive testing to ensure adequate coverage of said customization knobs.

You can watch Jesse and I talk about this phenomenon here: https://youtu.be/PCxz2LEmuL4?t=1643. We don't build kitchen sink libraries.

I think closing this is a good idea for now to set expectations.

Why has everybody write it's own adapters over and over again...?

There's no one standard way to serialize datetimes to JSON. JSON itself does not have a datetime type. I've seen them serialized as:

Picking just one of those is going to make everyone else upset. As Jake said, it's 4 simple lines of code to get exactly what you need.

On top of all this, java.time has many different classes (LocalDateTime, Instant, ZonedDateTime for example) that would need to be supported.

Well, I _assume_ that a toString() and parse() for the given JSR-310 classes when specified as target would be a good start as a overrideable default (which works just fine for all ISO-Strings) . You could at least provide them in the adapters library (instead of using the ancient java.util.Date). ISO 8601 is in fact what all Browser will use as well when serializing dates as this is W3 recommendation https://www.w3.org/QA/Tips/iso-date

It just works. And so should Moshi.

Was this page helpful?
0 / 5 - 0 ratings