Fixed issue 53 where default date instances were not getting
serialized/deserialized properly. Added support for time style as well by using he default formatter that uses time style.
This commit is contained in:
parent
4d73459b7e
commit
2b9fd47b72
|
@ -52,7 +52,7 @@ import java.util.TreeSet;
|
|||
final class DefaultTypeAdapters {
|
||||
|
||||
private static final DefaultDateTypeAdapter DATE_TYPE_ADAPTER =
|
||||
new DefaultDateTypeAdapter(DateFormat.DEFAULT);
|
||||
new DefaultDateTypeAdapter(DateFormat.getDateTimeInstance());
|
||||
@SuppressWarnings("unchecked")
|
||||
private static final EnumTypeAdapter ENUM_TYPE_ADAPTER = new EnumTypeAdapter();
|
||||
private static final UrlTypeAdapter URL_TYPE_ADAPTER = new UrlTypeAdapter();
|
||||
|
@ -169,11 +169,19 @@ final class DefaultTypeAdapters {
|
|||
public DefaultDateTypeAdapter(String datePattern) {
|
||||
this.format = new SimpleDateFormat(datePattern);
|
||||
}
|
||||
|
||||
DefaultDateTypeAdapter(DateFormat format) {
|
||||
this.format = format;
|
||||
}
|
||||
|
||||
public DefaultDateTypeAdapter(int style) {
|
||||
this.format = DateFormat.getDateInstance(style);
|
||||
}
|
||||
|
||||
public DefaultDateTypeAdapter(int dateStyle, int timeStyle) {
|
||||
this.format = DateFormat.getDateTimeInstance(dateStyle, timeStyle);
|
||||
}
|
||||
|
||||
public JsonElement serialize(Date src, Type typeOfSrc, JsonSerializationContext context) {
|
||||
String dateFormatAsString = format.format(src);
|
||||
return new JsonPrimitive(dateFormatAsString);
|
||||
|
|
|
@ -117,7 +117,8 @@ public final class Gson {
|
|||
* {@link java.math.BigDecimal}, and {@link java.math.BigInteger} classes. If you would prefer
|
||||
* to change the default representation, you can do so by registering a type adapter through
|
||||
* {@link GsonBuilder#registerTypeAdapter(Type, Object)}. </li>
|
||||
* <li>The default Date format is same as {@link java.text.DateFormat#DEFAULT}. You can change
|
||||
* <li>The default Date format is same as {@link java.text.DateFormat#DEFAULT}. This format
|
||||
* ignores the millisecond portion of the date during serialization. You can change
|
||||
* this by invoking {@link GsonBuilder#setDateFormat(int)} or
|
||||
* {@link GsonBuilder#setDateFormat(String)}. </li>
|
||||
* <li>By default, Gson ignores the {@link com.google.gson.annotations.Expose} annotation.
|
||||
|
|
|
@ -64,6 +64,7 @@ public final class GsonBuilder {
|
|||
private boolean serializeNulls;
|
||||
private String datePattern;
|
||||
private int dateStyle;
|
||||
private int timeStyle;
|
||||
|
||||
/**
|
||||
* Creates a GsonBuilder instance that can be used to build Gson with various configuration
|
||||
|
@ -85,6 +86,7 @@ public final class GsonBuilder {
|
|||
deserializers = new ParameterizedTypeHandlerMap<JsonDeserializer<?>>();
|
||||
serializeNulls = false;
|
||||
dateStyle = DateFormat.DEFAULT;
|
||||
timeStyle = DateFormat.DEFAULT;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -225,6 +227,28 @@ public final class GsonBuilder {
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures Gson to to serialize {@code Date} objects according to the style value provided.
|
||||
* You can call this method or {@link #setDateFormat(String)} multiple times, but only the last
|
||||
* invocation will be used to decide the serialization format.
|
||||
*
|
||||
* <p>Note that this style value should be one of the predefined constants in the
|
||||
* {@code DateFormat} class. See the documentation in {@link java.text.DateFormat} for more
|
||||
* information on the valid style constants.</p>
|
||||
*
|
||||
* @param dateStyle the predefined date style that date objects will be serialized/deserialized
|
||||
* to/from
|
||||
* @param timeStyle the predefined style for the time portion of the date objects
|
||||
* @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
|
||||
* @since 1.2
|
||||
*/
|
||||
public GsonBuilder setDateFormat(int dateStyle, int timeStyle) {
|
||||
this.dateStyle = dateStyle;
|
||||
this.timeStyle = timeStyle;
|
||||
this.datePattern = null;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures Gson for custom serialization or deserialization. This method combines the
|
||||
* registration of an {@link InstanceCreator}, {@link JsonSerializer}, and a
|
||||
|
@ -323,7 +347,8 @@ public final class GsonBuilder {
|
|||
ParameterizedTypeHandlerMap<JsonSerializer<?>> customSerializers = serializers.copyOf();
|
||||
ParameterizedTypeHandlerMap<JsonDeserializer<?>> customDeserializers = deserializers.copyOf();
|
||||
|
||||
addTypeAdaptersForDate(datePattern, dateStyle, customSerializers, customDeserializers);
|
||||
addTypeAdaptersForDate(datePattern, dateStyle, timeStyle, customSerializers,
|
||||
customDeserializers);
|
||||
customSerializers.registerIfAbsent(DefaultTypeAdapters.DEFAULT_SERIALIZERS);
|
||||
customDeserializers.registerIfAbsent(DefaultTypeAdapters.DEFAULT_DESERIALIZERS);
|
||||
|
||||
|
@ -337,15 +362,15 @@ public final class GsonBuilder {
|
|||
return gson;
|
||||
}
|
||||
|
||||
private static void addTypeAdaptersForDate(String datePattern, int dateStyle,
|
||||
private static void addTypeAdaptersForDate(String datePattern, int dateStyle, int timeStyle,
|
||||
ParameterizedTypeHandlerMap<JsonSerializer<?>> serializers,
|
||||
ParameterizedTypeHandlerMap<JsonDeserializer<?>> deserializers) {
|
||||
// NOTE: if a date pattern exists, then that style takes priority
|
||||
DefaultDateTypeAdapter dateTypeAdapter = null;
|
||||
if (datePattern != null && !"".equals(datePattern.trim())) {
|
||||
dateTypeAdapter = new DefaultDateTypeAdapter(datePattern);
|
||||
} else if (dateStyle != DateFormat.DEFAULT) {
|
||||
dateTypeAdapter = new DefaultDateTypeAdapter(dateStyle);
|
||||
} else if (dateStyle != DateFormat.DEFAULT && timeStyle != DateFormat.DEFAULT) {
|
||||
dateTypeAdapter = new DefaultDateTypeAdapter(dateStyle, timeStyle);
|
||||
}
|
||||
if (dateTypeAdapter != null
|
||||
&& !serializers.hasAnyHandlerFor(Date.class)
|
||||
|
|
|
@ -187,44 +187,52 @@ public class DefaultTypeAdaptersTest extends TestCase {
|
|||
public void testDefaultDateSerialization() {
|
||||
Date now = new Date();
|
||||
String json = gson.toJson(now);
|
||||
assertEquals("\"" + DateFormat.getDateInstance().format(now) + "\"", json);
|
||||
assertEquals("\"" + DateFormat.getDateTimeInstance().format(now) + "\"", json);
|
||||
}
|
||||
|
||||
public void testDefaultDateDeserialization() {
|
||||
Date date = new Date();
|
||||
assertEquals(date, gson.fromJson(gson.toJson(date), Date.class));
|
||||
String json = gson.toJson(date);
|
||||
Date extracted = gson.fromJson(json, Date.class);
|
||||
// Using comparison of string forms since the extracted date has lost the millisecond portion.
|
||||
assertEquals(date.toString(), extracted.toString());
|
||||
}
|
||||
|
||||
|
||||
public void testDefaultDateSerializationUsingBuilder() throws Exception {
|
||||
Gson gson = new GsonBuilder().create();
|
||||
Date now = new Date();
|
||||
String json = gson.toJson(now);
|
||||
assertEquals("\"" + DateFormat.getDateInstance().format(now) + "\"", json);
|
||||
assertEquals("\"" + DateFormat.getDateTimeInstance().format(now) + "\"", json);
|
||||
}
|
||||
|
||||
public void testDefaultDateDeserializationUsingBuilder() throws Exception {
|
||||
Gson gson = new GsonBuilder().create();
|
||||
Date now = new Date();
|
||||
String json = gson.toJson(now);
|
||||
assertEquals(now, gson.fromJson(json, Date.class));
|
||||
Date extracted = gson.fromJson(json, Date.class);
|
||||
assertEquals(now.toString(), extracted.toString());
|
||||
}
|
||||
|
||||
public void testDateSerializationWithPattern() throws Exception {
|
||||
String pattern = "yyyy-MM-dd";
|
||||
DateFormat formatter = new SimpleDateFormat(pattern);
|
||||
Gson gson = new GsonBuilder().setDateFormat(DateFormat.LONG).setDateFormat(pattern).create();
|
||||
Gson gson = new GsonBuilder().setDateFormat(DateFormat.FULL).setDateFormat(pattern).create();
|
||||
Date now = new Date();
|
||||
String json = gson.toJson(now);
|
||||
assertEquals("\"" + formatter.format(now) + "\"", json);
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public void testDateDeserializationWithPattern() throws Exception {
|
||||
String pattern = "yyyy-MM-dd";
|
||||
DateFormat formatter = new SimpleDateFormat(pattern);
|
||||
Gson gson = new GsonBuilder().setDateFormat(DateFormat.LONG).setDateFormat(pattern).create();
|
||||
Gson gson = new GsonBuilder().setDateFormat(DateFormat.FULL).setDateFormat(pattern).create();
|
||||
Date now = new Date();
|
||||
String json = gson.toJson(now);
|
||||
assertEquals(now, gson.fromJson(json, Date.class));
|
||||
Date extracted = gson.fromJson(json, Date.class);
|
||||
assertEquals(now.getYear(), extracted.getYear());
|
||||
assertEquals(now.getMonth(), extracted.getMonth());
|
||||
assertEquals(now.getDay(), extracted.getDay());
|
||||
}
|
||||
|
||||
private static class ClassWithBigDecimal {
|
||||
|
|
Loading…
Reference in New Issue