Search code examples
javagsonmarshalling

GSON: Is there any way to return 2 different date formats while marshalling


GsonBuilder.setDateFormat("yyyy-MM-dd HH:mm:ss") is appending 00:00:00 for date only fields. Is there any way to override this behavior as requirement is to show date only as well as date with time.


Solution

  • If you define a "date" a java.util.Date where hours, minutes and seconds are equal to zero, and "date with time" a Date where they are not. You coud do something like that:

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

    with CustomDateJsonSerializer define like this:

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