Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Retrofit GSON serialize Date from json string into java.util.date

I am using the Retrofit library for my REST calls. Most of what I have done has been smooth as butter but for some reason I am having issues converting JSON timestamp strings into java.util.Date objects. The JSON that is coming in looks like this.

{
    "date": "2013-07-16",
    "created_at": "2013-07-16T22:52:36Z",
} 

How can I tell Retrofit or Gson to convert these strings into java.util.Date objects?

like image 504
jpotts18 Avatar asked Aug 27 '13 18:08

jpotts18


3 Answers

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

RestAdapter restAdapter = new RestAdapter.Builder()
    .setEndpoint(API_BASE_URL)
    .setConverter(new GsonConverter.create(gson))
    .build();

Or the Kotlin equivalent:

val gson = GsonBuilder().setDateFormat("yyyy-MM-dd'T'HH:mm:ss").create()
RestAdapter restAdapter = Retrofit.Builder()
    .baseUrl(API_BASE_URL)
    .addConverterFactory(GsonConverterFactory.create(gson))
    .build()
    .create(T::class.java)

You can set your customized Gson parser to retrofit. More here: Retrofit Website

Look at Ondreju's response to see how to implement this in retrofit 2.

like image 161
gderaco Avatar answered Nov 03 '22 15:11

gderaco


@gderaco's answer updated to retrofit 2.0:

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

Retrofit retrofitAdapter = new Retrofit.Builder()
.baseUrl(API_BASE_URL)
.addConverterFactory(GsonConverterFactory.create(gson))
.build();
like image 93
Andrzej Purtak Avatar answered Nov 03 '22 15:11

Andrzej Purtak


Here is how I did it:

Create DateTime class extending Date and then write a custom deserializer:

public class DateTime extends java.util.Date {

    public DateTime(long readLong) {
        super(readLong);
    }

    public DateTime(Date date) {
        super(date.getTime());
    }       
}

Now for the deserializer part where we register both Date and DateTime converters:

public static Gson gsonWithDate(){
    final GsonBuilder builder = new GsonBuilder();

    builder.registerTypeAdapter(Date.class, new JsonDeserializer<Date>() {  

        final DateFormat df = new SimpleDateFormat("yyyy-MM-dd");  
        @Override  
        public Date deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {  
            try {  
                return df.parse(json.getAsString());  
            } catch (final java.text.ParseException e) {  
                e.printStackTrace();  
                return null;  
            }  
        }
    });

    builder.registerTypeAdapter(DateTime.class, new JsonDeserializer<DateTime>() {  

        final DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  
        @Override  
        public DateTime deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {  
            try {  
                return new DateTime(df.parse(json.getAsString()));  
            } catch (final java.text.ParseException e) {
                e.printStackTrace();  
                return null;  
            }  
        }
    });

    return builder.create();
}

And when you create your RestAdapter, do the following:

new RestAdapter.Builder().setConverter(gsonWithDate());

Your Foo should look like this:

class Foo {
    Date date;
    DateTime created_at;
}
like image 15
Kuanysh Raimbekov Avatar answered Nov 03 '22 15:11

Kuanysh Raimbekov