Настройте Gson для использования нескольких форматов даты

Теперь, когда я хочу сказать gson, как выполнять синтаксический анализ дат, я делаю:

Gson gson=  new GsonBuilder().setDateFormat("yyyy-MM-dd hh:mm").create();

Но у меня есть поля только с датой, а другие - только время, и я хочу, чтобы оба они были сохранены как объекты Date. Как я могу это сделать?

Ответ 1

Этот настраиваемый сериализатор/десериализатор может обрабатывать несколько форматов. Сначала вы можете попробовать разбор в одном формате, а затем, если это не удается, попробуйте второй формат. Это также должно обрабатывать нулевые даты без раздувания.

public class GsonDateDeSerializer implements JsonDeserializer<Date> {

...

private SimpleDateFormat format1 = new SimpleDateFormat("MMM dd, yyyy hh:mm:ss a");
private SimpleDateFormat format2 = new SimpleDateFormat("HH:mm:ss");

...

@Override
public Date deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
    try {
        String j = json.getAsJsonPrimitive().getAsString();
        return parseDate(j);
    } catch (ParseException e) {
        throw new JsonParseException(e.getMessage(), e);
    }
}

private Date parseDate(String dateString) throws ParseException {
    if (dateString != null && dateString.trim().length() > 0) {
        try {
            return format1.parse(dateString);
        } catch (ParseException pe) {
            return format2.parse(dateString);
        }
    } else {
        return null;
    }
}

}

Надеюсь, что это поможет, удачи в вашем проекте.

Ответ 2

GsonBuilder builder = new GsonBuilder();
builder.registerTypeAdapter(Date.class, new GsonDateDeSerializer());
gson = builder.create();

Над кодом будет применен новый созданный GsonDateDeSerializer как сериализатор даты GSON, созданный @reggoodwin

Ответ 3

Для более точного управления отдельными полями может быть предпочтительнее управлять форматом с помощью аннотаций:

@JsonAdapter(value = MyDateTypeAdapter.class)
private Date dateField;

... с адаптером типа по этим строкам:

public class MyDateTypeAdapter extends TypeAdapter<Date> {
    @Override
    public Date read(JsonReader in) throws IOException {
        // If in.peek isn't JsonToken.NULL, parse in.nextString() () appropriately
        // and return the Date...
    }

    @Override
    public void write(JsonWriter writer, Date value) throws IOException {
        // Set writer.value appropriately from value.get() (if not null)...
    }
}