3

The api I'm currently using returns dates (for the sake of this question, dates and datetimes are the same) in the form of "yyyy-MM-dd" and also in the typical ISO8601 format "2012-06-08T12:27:29.000-04:00"

How do you "cleanly" set up GSON to handle this? Or would my best approach be to treat dates as strings and output in the specific form needed using some custom getter in my model objects?

I'm currently doing the following, but parsing fails whenever I see a "yyyy-MM-dd" field.

return new GsonBuilder()
    .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
    .setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ")
    .create();

I'm ultimately using this in an Android + Retrofit context in case there are solutions available via that avenue.


Edit: Per the suggestion below, I created a custom TypeAdapter. My full solution can be seen (as a gist) here: https://gist.github.com/loeschg/2967da6c2029ca215258.

loeschg
  • 29,961
  • 26
  • 97
  • 150
  • you probably need to register a custom TypeAdapter for Date, that will try various formats. – njzk2 Dec 16 '14 at 19:25

1 Answers1

3

I woud do like that: (untested, though):

SimpleDateFormat[] formats = new SimpleDateFormat[] {
    new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ"),
    // Others formats go here
};

// ...

return new GsonBuilder()
    .registerTypeAdapter(Date.class, new TypeAdapter<Date>() {

        @Override
        public Date read(JsonReader reader) throws IOException {
            if (reader.peek() == JsonToken.NULL) {
                reader.nextNull();
                return null;
            }
            String dateAsString = reader.nextString();
            for (SimpleDateFormat format : formats) {
                try {
                    return format.parse(dateAsString);
                } catch (ParseException e) {}  // Ignore that, try next format
            }
            // No matching format found!
            return null;
        }
    })
    .create();

A custom type adapter that tries several formats.

njzk2
  • 38,969
  • 7
  • 69
  • 107