GSON:有没有办法在编组时返回2种不同的日期格式

时间:2014-10-28 10:53:50

标签: java gson marshalling

GsonBuilder.setDateFormat("yyyy-MM-dd HH:mm:ss")仅在00:00:00附加日期字段。 有没有办法覆盖这种行为,因为要求只显示日期和日期与时间。

3 个答案:

答案 0 :(得分:2)

如果您定义一个“日期”,其中小时,分钟和秒等于零的“{1}}”和“{时间日期”为java.util.Date,而Date则不是。你可以这样做:

    GsonBuilder builder = new GsonBuilder();
    builder.registerTypeAdapter(Date.class, new CustomDateJsonSerializer());

CustomDateJsonSerializer定义如下:

public class CustomDateJsonSerializer implements JsonSerializer<Date>, JsonDeserializer<Date> {
    private static final TimeZone UTC_TIME_ZONE = TimeZone.getTimeZone("UTC");
    private static final Pattern DATE_PATTERN = Pattern.compile("\\d{4}-\\d{2}-\\d{2}");
    private static final Pattern DATE_TIME_PATTERN = Pattern.compile("\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}");

    public Date deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
        String asString = json.getAsString();
        try {
            if (DATE_PATTERN.matcher(asString).matches()) {
                return getDateFormat().parse(asString);
            } else if (DATE_TIME_PATTERN.matcher(asString).matches()) {
                return getDateTimeFormat().parse(asString);
            } else {
                throw new JsonParseException("Could not parse to date: " + json);
            }
        } catch (ParseException e) {
            throw new JsonParseException("Could not parse to date: " + json, e);
        }
    }

    private static DateFormat getDateFormat() {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("YYYY-MM-dd");
        simpleDateFormat.setTimeZone(UTC_TIME_ZONE);
        return simpleDateFormat;
    }

    private static DateFormat getDateTimeFormat() {
        SimpleDateFormat dateFormat = new SimpleDateFormat("YYYY-MM-dd HH:mm:ss");
        dateFormat.setTimeZone(UTC_TIME_ZONE);
        return dateFormat;
    }

    public JsonElement serialize(Date date, Type typeOfSrc, JsonSerializationContext context) {
        Calendar calendar = Calendar.getInstance(UTC_TIME_ZONE);
        calendar.setTime(date);
        int hours = calendar.get(Calendar.HOUR);
        int minutes = calendar.get(Calendar.MINUTE);
        int seconds = calendar.get(Calendar.SECOND);
        String dateFormatted;
        if (hours == 0 && minutes == 0 && seconds == 0) {
            dateFormatted = getDateFormat().format(date);
        } else {
            dateFormatted = getDateTimeFormat().format(date);
        }
        return new JsonPrimitive(dateFormatted);
    }
}

答案 1 :(得分:1)

您需要定义两个不同的Gson TypeAdapter实现。

然后在可序列化类的相应Date字段中指定您要使用的TypeAdapter。

使用如下所示的自定义类型适配器和字段注释:

@JsonAdapter(DatePartOnlyGsonAdapter.class)
Date whenever; 

public Date getWhenever() {
    return whenever;
}

当你使用yyyy-MM-dd属性继承代码时,这是一个只输出LocalDate格式的类型适配器,使用Java8的java.util.Date进行格式化:(

import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;

import java.io.IOException;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Date;

public class DatePartOnlyGsonAdapter extends TypeAdapter<Date> {

    @Override
    public void write(JsonWriter out, Date src) throws IOException {
        if (src == null) {
            out.nullValue();
            return;
        }
        LocalDate d = new java.sql.Date(src.getTime()).toLocalDate();
        out.value(d.format(DateTimeFormatter.ISO_DATE));
    }

    @Override
    public Date read(JsonReader in) throws IOException {
        throw new IllegalStateException("Gson Date reader not implemented");
    }
}

答案 2 :(得分:0)

Joda-Time | java.time

如果您只想要一个没有任何时间或时区的日期,请使用另一个库而不是java.util.Date和.Calendar类。

而是在Java 8中使用Joda-Time或java.time包。两者都提供LocalDate类。

Bonus:默认情况下,它们都使用标准ISO 8601格式来生成和解析字符串表示。