Question

When I use the following piece of 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}]

To three Product objects with the fields 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 the JSON) it fails with a JsonSyntaxException : 2014-05-13T00:00:00

So, my question: How can I 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 both didn't work.

NOTE: I Googled a bit and most solutions use serializers & deserializers in both the Java code and used API. But since I can't modify my JSON send from my C# Web API, this isn't an option for me. I can only add things at the receiver's end (my Android App).

PS: I might have a solution, though it's a bit extra work & contains a potentially slowing for-loop: I change the Date Date in my Order-class to String Date (so the Gson parsing will put it in that String-field), then add a Date mDate and after Gson has parsed the complete JSON-array of Orders, I parse the Dates to mDates in a for-loop.. Still, this solution is pretty inefficient, so if anyone know how to do it within GsonBuilder itself I would appreciate it.

Thanks in advance for the responses.

Was it helpful?

Solution

Ok, I was close, but made a small (and pretty obvious) mistake..

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 now use a deseralizer as well, but only in my Android part. The reason why I changed it is as follows:

  • When I had a differently formatted date or a date that was null, I would get a JsonParseException on the entire JSON, so none of my Order-Objects were created.
  • Now that I use this seralizer and a Date appears to be of an invalid format or null, it just makes that Date in the Order-object null, but still converts everything as it should with a 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();
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top