GSON: Is there a way to return 2 different date formats when sorting

GsonBuilder.setDateFormat("yyyy-MM-dd HH:mm:ss")

adds 00:00:00 for date fields only. Is there a way to override this behavior as the requirement is to only show the date as well as the date over time.

+3


source to share


3 answers


If you define "date" a java.util.Date

where hours, minutes and seconds are zero, and "date with time" a Date

where they are missing. You can do something like this:

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

      



s is CustomDateJsonSerializer

defined as follows:

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

      

+2


source


You need to define two different Gorder TypeAdapter implementations.

Then specify in the appropriate Date field in your serialized class which TypeAdapter you want to use.

Use a custom type adapter as shown below with field annotation:



@JsonAdapter(DatePartOnlyGsonAdapter.class)
Date whenever; 

public Date getWhenever() {
    return whenever;
}

      

It uses a type of adapter that displays only the format yyyy-MM-dd

, using Java8 LocalDate

formatting when legacy code using the properties 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");
    }
}

      

+1


source


Joda-Time | java.time

If you only want a date without any time of day or time zone, then use a different library rather than the java.util.Date and .Calendar classes.

Use either Joda-Time or the java.time package in Java 8 instead. Both offer a class LocalDate

.

Bonus: By default, both use the ISO 8601 standard format for generating and parsing String representations.

0


source







All Articles