32

私のサーバー JSON は、2 つの異なるタイプの DateFormat を返します。"MMM dd, yyyy" および "MMM dd, yyyy HH:mm:ss"

JSON を次のように変換すると問題ありません。

Gson gson = new GsonBuilder().setDateFormat("MMM dd, yyyy").create();

しかし、詳細な日付形式が必要で、これに変更すると、例外 com.google.gson.JsonSyntaxException: Mar 21, 2013 がスローされます

Gson gson = new GsonBuilder().setDateFormat("MMM dd, yyyy HH:mm:ss").create();

gson が Json 変換のために 2 つの異なる DateFormat を処理する方法はありますか?

4

3 に答える 3

11

答えは受け入れられましたが、同様のより拡張可能なソリューションを共有したいと思いました。ここで要点を見つけることができます。

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);
        }
    }
}

次に、さまざまな形式を次のように登録します...

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();

次に、各形式がクラスにマップされます...

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");
    }
}
于 2014-03-02T19:39:53.007 に答える
2

カスタムの逆シリアル化が必要です。適切な解決策は、一度に複数の日付形式を処理できる Apache Commons DateUtil を利用することです。また、JodaTime API にも同様の機能がある場合があります。

于 2013-03-23T19:54:00.337 に答える