Reputation: 43
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.
Upvotes: 3
Views: 1822
Reputation: 5445
You need to define two different Gson TypeAdapter implementations.
Then specify on the appropriate Date field on your serializable class which TypeAdapter you wish to use.
Use a custom type adapter like below with the field annotation:
@JsonAdapter(DatePartOnlyGsonAdapter.class)
Date whenever;
public Date getWhenever() {
return whenever;
}
Here's a type adapter which outputs just the yyyy-MM-dd
format, using Java8's LocalDate
to do formatting, when you have inherited code using java.util.Date
properties :(
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");
}
}
Upvotes: 1
Reputation: 338775
If you want a date only without any time of day or time zone, use another library rather than the java.util.Date and .Calendar classes.
Instead use either Joda-Time or java.time package in Java 8. Both offer a LocalDate
class.
Bonus: By default both use the standard ISO 8601 format for generating and parsing String representations.
Upvotes: 0
Reputation: 3599
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);
}
}
Upvotes: 2