Search code examples
javaandroidgsondate-formatunix-timestamp

Using gson dateformat to serialize and deserialize unix-timestamps


I am using Gson to serialize/deserialize my pojos and currently looking for a clean way to tell Gson to parse/output date attributes as unix-timestamps. Here's my attempt:

Gson gson = new GsonBuilder().setDateFormat("U").create();

Comming from PHP where "U" is the dateformat used to serialize/deserialize date as unix-timestamps, when running my attempt code, I am a RuntimeException:

Unknown pattern character 'U'

I am assuming that Gson uses SimpleDateformat under the hood which doesn't define the letter "U".

I could implement a custom DateTypeAdapter but I am looking for a cleaner way to achieve that. Simply changing the DateFormat would be great.


Solution

  • Creating a custom TypeAdapter (UnixTimestampAdapter) was the way to go.

    UnixTimestampAdapter

    public class UnixTimestampAdapter extends TypeAdapter<Date> {
    
        @Override
        public void write(JsonWriter out, Date value) throws IOException {
            if (value == null) {
                out.nullValue();
                return;
            }
            out.value(value.getTime() / 1000);
        }
    
        @Override
        public Date read(JsonReader in) throws IOException {
            if (in.peek() == JsonToken.NULL) {
                in.nextNull();
                return null;
            }
            return new Date(in.nextLong() * 1000);
        }
    
    }
    

    Now, you have to options (depending on your use case):

    1 - If you want apply this serialization on all your date fields then register UnixTimestampAdapter upon creating your Gson instance:

    Gson gson = new GsonBuilder()
                       .registerTypeAdapter(Date.class, new UnixTimestampAdapter())
                       .create();
    

    2 - Or annotate your date fields with @JsonAdapter (as suggested by @Marcono1234) if you want it applied only to some specific fields.

    class Person {
        @JsonAdapter(UnixTimestampAdapter.class)
        private Date birthday;
    }