Use the date format for java.sql.Date and java.sql.Timestamp.
Fixes issue 230.
This commit is contained in:
parent
4efb133b4a
commit
f718784f33
|
@ -17,7 +17,6 @@
|
||||||
package com.google.gson;
|
package com.google.gson;
|
||||||
|
|
||||||
import com.google.gson.internal.$Types;
|
import com.google.gson.internal.$Types;
|
||||||
|
|
||||||
import java.lang.reflect.ParameterizedType;
|
import java.lang.reflect.ParameterizedType;
|
||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
|
@ -301,6 +300,10 @@ final class DefaultTypeAdapters {
|
||||||
return DEFAULT_INSTANCE_CREATORS;
|
return DEFAULT_INSTANCE_CREATORS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This type adapter supports three subclasses of date: Date, Timestamp, and
|
||||||
|
* java.sql.Date.
|
||||||
|
*/
|
||||||
static final class DefaultDateTypeAdapter implements JsonSerializer<Date>, JsonDeserializer<Date> {
|
static final class DefaultDateTypeAdapter implements JsonSerializer<Date>, JsonDeserializer<Date> {
|
||||||
private final DateFormat enUsFormat;
|
private final DateFormat enUsFormat;
|
||||||
private final DateFormat localFormat;
|
private final DateFormat localFormat;
|
||||||
|
@ -345,6 +348,19 @@ final class DefaultTypeAdapters {
|
||||||
if (!(json instanceof JsonPrimitive)) {
|
if (!(json instanceof JsonPrimitive)) {
|
||||||
throw new JsonParseException("The date should be a string value");
|
throw new JsonParseException("The date should be a string value");
|
||||||
}
|
}
|
||||||
|
Date date = deserializeToDate(json);
|
||||||
|
if (typeOfT == Date.class) {
|
||||||
|
return date;
|
||||||
|
} else if (typeOfT == Timestamp.class) {
|
||||||
|
return new Timestamp(date.getTime());
|
||||||
|
} else if (typeOfT == java.sql.Date.class) {
|
||||||
|
return new java.sql.Date(date.getTime());
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException(getClass() + " cannot deserialize to " + typeOfT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Date deserializeToDate(JsonElement json) {
|
||||||
synchronized (localFormat) {
|
synchronized (localFormat) {
|
||||||
try {
|
try {
|
||||||
return localFormat.parse(json.getAsString());
|
return localFormat.parse(json.getAsString());
|
||||||
|
|
|
@ -18,6 +18,7 @@ package com.google.gson;
|
||||||
|
|
||||||
import com.google.gson.internal.$Preconditions;
|
import com.google.gson.internal.$Preconditions;
|
||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
|
import java.sql.Timestamp;
|
||||||
import java.text.DateFormat;
|
import java.text.DateFormat;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
@ -400,6 +401,9 @@ public final class GsonBuilder {
|
||||||
* call this method or {@link #setDateFormat(int)} multiple times, but only the last invocation
|
* call this method or {@link #setDateFormat(int)} multiple times, but only the last invocation
|
||||||
* will be used to decide the serialization format.
|
* will be used to decide the serialization format.
|
||||||
*
|
*
|
||||||
|
* <p>The date format will be used to serialize and deserialize {@link java.util.Date}, {@link
|
||||||
|
* java.sql.Timestamp} and {@link java.sql.Date}.
|
||||||
|
*
|
||||||
* <p>Note that this pattern must abide by the convention provided by {@code SimpleDateFormat}
|
* <p>Note that this pattern must abide by the convention provided by {@code SimpleDateFormat}
|
||||||
* class. See the documentation in {@link java.text.SimpleDateFormat} for more information on
|
* class. See the documentation in {@link java.text.SimpleDateFormat} for more information on
|
||||||
* valid date and time patterns.</p>
|
* valid date and time patterns.</p>
|
||||||
|
@ -679,12 +683,19 @@ public final class GsonBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dateTypeAdapter != null) {
|
if (dateTypeAdapter != null) {
|
||||||
if (!serializers.hasSpecificHandlerFor(Date.class)) {
|
registerIfAbsent(Date.class, serializers, dateTypeAdapter);
|
||||||
serializers.register(Date.class, dateTypeAdapter);
|
registerIfAbsent(Date.class, deserializers, dateTypeAdapter);
|
||||||
}
|
registerIfAbsent(Timestamp.class, serializers, dateTypeAdapter);
|
||||||
if (!deserializers.hasSpecificHandlerFor(Date.class)) {
|
registerIfAbsent(Timestamp.class, deserializers, dateTypeAdapter);
|
||||||
deserializers.register(Date.class, dateTypeAdapter);
|
registerIfAbsent(java.sql.Date.class, serializers, dateTypeAdapter);
|
||||||
|
registerIfAbsent(java.sql.Date.class, deserializers, dateTypeAdapter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static <T> void registerIfAbsent(Class<?> type,
|
||||||
|
ParameterizedTypeHandlerMap<T> adapters, T adapter) {
|
||||||
|
if (!adapters.hasSpecificHandlerFor(type)) {
|
||||||
|
adapters.register(type, adapter);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,13 @@
|
||||||
*/
|
*/
|
||||||
package com.google.gson.functional;
|
package com.google.gson.functional;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.google.gson.GsonBuilder;
|
||||||
|
import com.google.gson.JsonDeserializationContext;
|
||||||
|
import com.google.gson.JsonDeserializer;
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
|
import com.google.gson.JsonParseException;
|
||||||
|
import com.google.gson.reflect.TypeToken;
|
||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
|
@ -36,17 +43,8 @@ import java.util.Set;
|
||||||
import java.util.TimeZone;
|
import java.util.TimeZone;
|
||||||
import java.util.TreeSet;
|
import java.util.TreeSet;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import junit.framework.TestCase;
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
|
||||||
import com.google.gson.GsonBuilder;
|
|
||||||
import com.google.gson.JsonDeserializationContext;
|
|
||||||
import com.google.gson.JsonDeserializer;
|
|
||||||
import com.google.gson.JsonElement;
|
|
||||||
import com.google.gson.JsonParseException;
|
|
||||||
import com.google.gson.reflect.TypeToken;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Functional test for Json serialization and deserialization for common classes for which default
|
* Functional test for Json serialization and deserialization for common classes for which default
|
||||||
* support is provided in Gson. The tests for Map types are available in {@link MapTest}.
|
* support is provided in Gson. The tests for Map types are available in {@link MapTest}.
|
||||||
|
@ -380,15 +378,53 @@ public class DefaultTypeAdaptersTest extends TestCase {
|
||||||
|
|
||||||
// http://code.google.com/p/google-gson/issues/detail?id=230
|
// http://code.google.com/p/google-gson/issues/detail?id=230
|
||||||
public void testDateSerializationInCollection() throws Exception {
|
public void testDateSerializationInCollection() throws Exception {
|
||||||
|
Type listOfDates = new TypeToken<List<Date>>() {}.getType();
|
||||||
TimeZone defaultTimeZone = TimeZone.getDefault();
|
TimeZone defaultTimeZone = TimeZone.getDefault();
|
||||||
TimeZone.setDefault(TimeZone.getTimeZone("America/Los_Angeles"));
|
TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
|
||||||
Locale defaultLocale = Locale.getDefault();
|
Locale defaultLocale = Locale.getDefault();
|
||||||
Locale.setDefault(Locale.US);
|
Locale.setDefault(Locale.US);
|
||||||
try {
|
try {
|
||||||
Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd").create();
|
Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd").create();
|
||||||
List<Date> dates = Arrays.asList(new Date(0));
|
List<Date> dates = Arrays.asList(new Date(0));
|
||||||
String json = gson.toJson(dates, new TypeToken<List<Date>>() {}.getType());
|
String json = gson.toJson(dates, listOfDates);
|
||||||
assertEquals("[\"1969-12-31\"]", json);
|
assertEquals("[\"1970-01-01\"]", json);
|
||||||
|
assertEquals(0L, gson.<List<Date>>fromJson("[\"1970-01-01\"]", listOfDates).get(0).getTime());
|
||||||
|
} finally {
|
||||||
|
TimeZone.setDefault(defaultTimeZone);
|
||||||
|
Locale.setDefault(defaultLocale);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// http://code.google.com/p/google-gson/issues/detail?id=230
|
||||||
|
public void testTimestampSerialization() throws Exception {
|
||||||
|
TimeZone defaultTimeZone = TimeZone.getDefault();
|
||||||
|
TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
|
||||||
|
Locale defaultLocale = Locale.getDefault();
|
||||||
|
Locale.setDefault(Locale.US);
|
||||||
|
try {
|
||||||
|
Timestamp timestamp = new Timestamp(0L);
|
||||||
|
Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd").create();
|
||||||
|
String json = gson.toJson(timestamp, Timestamp.class);
|
||||||
|
assertEquals("\"1970-01-01\"", json);
|
||||||
|
assertEquals(0, gson.fromJson("\"1970-01-01\"", Timestamp.class).getTime());
|
||||||
|
} finally {
|
||||||
|
TimeZone.setDefault(defaultTimeZone);
|
||||||
|
Locale.setDefault(defaultLocale);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// http://code.google.com/p/google-gson/issues/detail?id=230
|
||||||
|
public void testSqlDateSerialization() throws Exception {
|
||||||
|
TimeZone defaultTimeZone = TimeZone.getDefault();
|
||||||
|
TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
|
||||||
|
Locale defaultLocale = Locale.getDefault();
|
||||||
|
Locale.setDefault(Locale.US);
|
||||||
|
try {
|
||||||
|
java.sql.Date sqlDate = new java.sql.Date(0L);
|
||||||
|
Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd").create();
|
||||||
|
String json = gson.toJson(sqlDate, Timestamp.class);
|
||||||
|
assertEquals("\"1970-01-01\"", json);
|
||||||
|
assertEquals(0, gson.fromJson("\"1970-01-01\"", java.sql.Date.class).getTime());
|
||||||
} finally {
|
} finally {
|
||||||
TimeZone.setDefault(defaultTimeZone);
|
TimeZone.setDefault(defaultTimeZone);
|
||||||
Locale.setDefault(defaultLocale);
|
Locale.setDefault(defaultLocale);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user