15

I recently switched some of our serialization from Jackson to Gson. Found out that Jackson serializes dates to longs.

But, Gson serializes Dates to strings by default.

How do I serialize dates to longs when using Gson? Thanks.

AlikElzin-kilaka
  • 34,335
  • 35
  • 194
  • 277

2 Answers2

33

First type adapter does the deserialization and the second one the serialization.

Gson gson = new GsonBuilder()
        .registerTypeAdapter(Date.class, (JsonDeserializer<Date>) (json, typeOfT, context) -> new Date(json.getAsJsonPrimitive().getAsLong()))
        .registerTypeAdapter(Date.class, (JsonSerializer<Date>) (date, type, jsonSerializationContext) -> new JsonPrimitive(date.getTime()))
        .create();

Usage:

String jsonString = gson.toJson(objectWithDate1);
ClassWithDate objectWithDate2 = gson.fromJson(jsonString, ClassWithDate.class);
assert objectWithDate1.equals(objectWithDate2);
AlikElzin-kilaka
  • 34,335
  • 35
  • 194
  • 277
15

You can do both direction with one type adapter:

public class DateLongFormatTypeAdapter extends TypeAdapter<Date> {

    @Override
    public void write(JsonWriter out, Date value) throws IOException {
        if(value != null) out.value(value.getTime());
        else out.nullValue();
    }

    @Override
    public Date read(JsonReader in) throws IOException {
        return new Date(in.nextLong());
    }

}

Gson builder:

Gson gson = new GsonBuilder()
        .registerTypeAdapter(Date.class, new DateLongFormatTypeAdapter())
        .create();
Eng.Fouad
  • 115,165
  • 71
  • 313
  • 417
Daniel Hári
  • 7,254
  • 5
  • 39
  • 54
  • Nice. Especially the single type. The `nextLong()` is a bit implicit :( Upvoted. – AlikElzin-kilaka Mar 28 '18 at 14:46
  • 1
    Thanks. Actually we expect a long, and that is only a conversion shortcut provided by gson, so I don't see any problem with that. Documentation: "Returns the long value of the next token, consuming it. If the next token is a string, this method will attempt to parse it as a long. If the next token's numeric value cannot be exactly represented by a Java long, this method throws." – Daniel Hári Mar 28 '18 at 18:17