Gson to json conversion with two DateFormat

后端 未结 3 1266
隐瞒了意图╮
隐瞒了意图╮ 2020-12-02 18:39

My server JSON is returning with two different type of DateFormat. \"MMM dd, yyyy\" and \"MMM dd, yyyy HH:mm:ss\"

When I convert the JSON with the following it is fi

相关标签:
3条回答
  • 2020-12-02 19:17

    Although the answer has been accepted I wanted to share a similar yet more extensible solution. You can find the gist here.

    DateDeserializer.java

    public class DateDeserializer<T extends Date> implements JsonDeserializer<T> {
    
        private static final String TAG = DateDeserializer.class.getSimpleName();
    
        private final SimpleDateFormat mSimpleDateFormat;
        private final Class<T> mClazz;
    
        public DateDeserializer(SimpleDateFormat simpleDateFormat, Class<T> clazz) {
            mSimpleDateFormat = simpleDateFormat;
            mClazz = clazz;
        }
    
        @Override
        public T deserialize(JsonElement element, Type arg1, JsonDeserializationContext context) throws JsonParseException {
            String dateString = element.getAsString();
            try {
                T date = mClazz.newInstance();
                date.setTime(mSimpleDateFormat.parse(dateString).getTime());
                return date;
            } catch (InstantiationException e) {
                throw new JsonParseException(e.getMessage(), e);
            } catch (IllegalAccessException e) {
                throw new JsonParseException(e.getMessage(), e);
            } catch (ParseException e) {
                throw new JsonParseException(e.getMessage(), e);
            }
        }
    }
    

    Then register the different formats as...

    sGson = new GsonBuilder()
                        .registerTypeAdapter(Event.EventDateTime.class,
                                new DateDeserializer<Event.EventDateTime>(
                                        Event.EventDateTime.DATE_FORMAT, Event.EventDateTime.class))
                        .registerTypeAdapter(Event.StartEndDateTime.class,
                                new DateDeserializer<Event.StartEndDateTime>(
                                        Event.StartEndDateTime.DATE_FORMAT, Event.StartEndDateTime.class))
                        .registerTypeAdapter(Event.SimpleDate.class,
                                new DateDeserializer<Event.SimpleDate>(
                                        Event.SimpleDate.DATE_FORMAT, Event.SimpleDate.class))
                        .create();
    

    Each format is then mapped to a class...

    public class Event {
    
        @SerializedName("created")
        private EventDateTime mCreated;
    
        //@SerializedName("updated")
        private EventDateTime mUpdated;
    
        ...
    
        @SerializedName("start")
        private ConditionalDateTime mStart;
    
        @SerializedName("end")
        private ConditionalDateTime mEnd;
    
        public static class ConditionalDateTime {
            @SerializedName("dateTime")
            private StartEndDateTime mDateTime;
    
            @SerializedName("date")
            private SimpleDate mDate;
    
            public SimpleDate getDate() {
                return mDate;
            }
    
            public StartEndDateTime getDateTime() {
                return mDateTime;
            }
    
            /**
             * If it is an all day event then only date is populated (not DateTime)
             * @return
             */
            public boolean isAllDayEvent() {
                return mDate != null;
            }
        }
    
        public static class EventDateTime extends Date {
            public static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
        }
    
        public static class StartEndDateTime extends Date {
            public static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZZZZZ");
        }
    
        public static class SimpleDate extends java.util.Date {
            public static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd");
        }
    }
    
    0 讨论(0)
  • 2020-12-02 19:31

    I was facing the same issue. Here is my solution via custom deserialization:

    new GsonBuilder().registerTypeAdapter(Date.class, new DateDeserializer());
    
    private static final String[] DATE_FORMATS = new String[] {
            "MMM dd, yyyy HH:mm:ss",
            "MMM dd, yyyy"
    };
    
    
    private class DateDeserializer implements JsonDeserializer<Date> {
    
        @Override
        public Date deserialize(JsonElement jsonElement, Type typeOF,
                JsonDeserializationContext context) throws JsonParseException {
            for (String format : DATE_FORMATS) {
                try {
                    return new SimpleDateFormat(format, Locale.US).parse(jsonElement.getAsString());
                } catch (ParseException e) {
                }
            }
            throw new JsonParseException("Unparseable date: \"" + jsonElement.getAsString()
                    + "\". Supported formats: " + Arrays.toString(DATE_FORMATS));
        }
    }
    
    0 讨论(0)
  • 2020-12-02 19:31

    Custom deserialization is necessary. A decent solution would be to make use of the Apache Commons DateUtil, which can handle multiple date formats at once. Also, the JodaTime API might have a similar feature.

    0 讨论(0)
提交回复
热议问题