Java – Android/Java – Gson parses from JSON string to object – date issue

Android/Java – Gson parses from JSON string to object – date issue… here is a solution to the problem.

Android/Java – Gson parses from JSON string to object – date issue

When I use the following code in Android:

// convert JSON string to a List of Product objects
Type listType = new TypeToken<List<Product>>(){}.getType();
p = (List<Product>)new Gson().fromJson(json, listType);

It will convert:

[{"$id":"1","ProductId":17,"Name":"Product1","Price":1.49,"Visible":true},
{"$id":"2","ProductId":19,"Name":"Product2","Price":3.89,"Visible":true},
{"$id":"3","ProductId":20,"Name":"Product3","Price":0.32,"Visible":true}]

The fields of the three product objects int ProductId, String Name, double Price, boolean Visible, and perhaps some other fields.


When I try the same with Orders, which contains a C# DateTime in JSON, it fails with JsonSyntaxException: 2014-05-13T00:00:00

So, my question is: how to successfully convert a JSON string containing a date string (2014-05-13T00:00:00) to a Java.util.Date object?

I did try the following:

// convert JSON string to a List of Order objects
Type listType = new TypeToken<List<Order>>(){}.getType();
Gson gson = new GsonBuilder().setDateFormat(DateFormat.FULL).create();
o = (List<Order>)gson.fromJson(json, listType);

and

// convert JSON string to a List of Order objects
Type listType = new TypeToken<List<Order>>(){}.getType();
Gson gson = new GsonBuilder().setDateFormat(DateFormat.FULL, DateFormat.FULL).create();
o = (List<Order>)gson.fromJson(json, listType);

But neither works.

Note: I googled and most solutions use serializers and deserializers in their Java code and APIs used. But since I can’t modify the JSON sent from my C# web API, it’s not my choice. I can only add content on the receiver side (my Android app).

PS: I probably have a solution, although it’s a bit extra work and contains a for loop that might slow down: I changed Date in my Order-class to String Date (so gson parsing would put it in that string field) and then added a Date mDate and JSON array to complete the order after gson parses, I parse Dates to mDates in a for loop. This solution is inefficient, though, so I would appreciate it if anyone knew how to do this in GsonBuilder.

Thank you in advance for your reply.

Solution

Well, I’m close, but made a small mistake (and obviously)…

Instead of:

Gson gson = new GsonBuilder().setDateFormat(DateFormat.FULL, DateFormat.FULL).create();

I need to use:

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

Edit:

I also use the deserializer now, but only for my Android part. Here’s why I changed it:

  • When I have a date in a different format or a date that is empty, I get a JsonParseException on the whole JSON, so none of my order objects are created.
  • Now I use this serializer and the date seems to be invalid format or empty, it just makes the date empty in the order object, but still transforms everything with the resulting order list. <

Code:

try{
     Convert JSON-string to a List of Order objects
    Type listType = new TypeToken<ArrayList<Order>>(){}.getType();
    GsonBuilder gsonBuilder = new GsonBuilder();
    gsonBuilder.registerTypeAdapter(Date.class, new JsonDeserializer<Date>() {
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.ENGLISH);
        @Override
        public Date deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
            try{
                return df.parse(json.getAsString());
            }
            catch(ParseException ex){
                return null;
            }
        }
    });
    Gson dateGson = gsonBuilder.create();
    orders = dateGson.fromJson(json, listType);
}
catch(JsonParseException ex){
    ex.printStackTrace();
}

Related Problems and Solutions