diff --git a/gson/src/main/java/com/google/gson/DefaultTypeAdapters.java b/gson/src/main/java/com/google/gson/DefaultTypeAdapters.java index 67fd70a8..2779c708 100644 --- a/gson/src/main/java/com/google/gson/DefaultTypeAdapters.java +++ b/gson/src/main/java/com/google/gson/DefaultTypeAdapters.java @@ -36,8 +36,6 @@ import com.google.gson.internal.ParameterizedTypeHandlerMap; */ final class DefaultTypeAdapters { - private static final DefaultDateTypeAdapter DATE_TYPE_ADAPTER = new DefaultDateTypeAdapter(); - // The constants DEFAULT_SERIALIZERS, DEFAULT_DESERIALIZERS, and DEFAULT_INSTANCE_CREATORS // must be defined after the constants for the type adapters. Otherwise, the type adapter // constants will appear as nulls. @@ -51,10 +49,6 @@ final class DefaultTypeAdapters { private static ParameterizedTypeHandlerMap> createDefaultSerializers() { ParameterizedTypeHandlerMap> map = new ParameterizedTypeHandlerMap>(); - - map.register(Date.class, DATE_TYPE_ADAPTER, true); - map.register(Timestamp.class, DATE_TYPE_ADAPTER, true); - map.makeUnmodifiable(); return map; } @@ -62,8 +56,6 @@ final class DefaultTypeAdapters { private static ParameterizedTypeHandlerMap> createDefaultDeserializers() { ParameterizedTypeHandlerMap> map = new ParameterizedTypeHandlerMap>(); - map.register(Date.class, wrapDeserializer(DATE_TYPE_ADAPTER), true); - map.makeUnmodifiable(); return map; } @@ -75,11 +67,6 @@ final class DefaultTypeAdapters { return map; } - @SuppressWarnings("unchecked") - private static JsonDeserializer wrapDeserializer(JsonDeserializer deserializer) { - return new JsonDeserializerExceptionWrapper(deserializer); - } - /** * This type adapter supports three subclasses of date: Date, Timestamp, and * java.sql.Date. diff --git a/gson/src/main/java/com/google/gson/Gson.java b/gson/src/main/java/com/google/gson/Gson.java index 353c171a..12e44f8f 100644 --- a/gson/src/main/java/com/google/gson/Gson.java +++ b/gson/src/main/java/com/google/gson/Gson.java @@ -16,6 +16,21 @@ package com.google.gson; +import java.io.EOFException; +import java.io.IOException; +import java.io.Reader; +import java.io.StringReader; +import java.io.StringWriter; +import java.io.Writer; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.lang.reflect.Type; +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + import com.google.gson.internal.ConstructorConstructor; import com.google.gson.internal.ParameterizedTypeHandlerMap; import com.google.gson.internal.Primitives; @@ -36,20 +51,6 @@ import com.google.gson.stream.JsonReader; import com.google.gson.stream.JsonToken; import com.google.gson.stream.JsonWriter; import com.google.gson.stream.MalformedJsonException; -import java.io.EOFException; -import java.io.IOException; -import java.io.Reader; -import java.io.StringReader; -import java.io.StringWriter; -import java.io.Writer; -import java.lang.reflect.Field; -import java.lang.reflect.Modifier; -import java.lang.reflect.Type; -import java.math.BigDecimal; -import java.math.BigInteger; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; /** * This is the main class for using Gson. Gson is typically used by first constructing a @@ -254,6 +255,7 @@ public final class Gson { .factory(TypeAdapters.LOCALE_FACTORY) .factory(TypeAdapters.INET_ADDRESS_FACTORY) .factory(TypeAdapters.BIT_SET_FACTORY) + .factory(TypeAdapters.DATE_FACTORY) .factory(TypeAdapters.CALENDAR_FACTORY) .factory(TypeAdapters.SQL_TIME_FACTORY) .factory(TypeAdapters.SQL_DATE_FACTORY) diff --git a/gson/src/main/java/com/google/gson/internal/bind/TypeAdapters.java b/gson/src/main/java/com/google/gson/internal/bind/TypeAdapters.java index c4a0a187..f4c1f014 100644 --- a/gson/src/main/java/com/google/gson/internal/bind/TypeAdapters.java +++ b/gson/src/main/java/com/google/gson/internal/bind/TypeAdapters.java @@ -32,6 +32,7 @@ import java.util.Date; import java.util.GregorianCalendar; import java.util.Locale; import java.util.StringTokenizer; +import java.util.TimeZone; import java.util.UUID; import com.google.gson.JsonIOException; @@ -411,6 +412,52 @@ public final class TypeAdapters { } }; + private static DateFormat buildIso8601Format() { + DateFormat iso8601Format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US); + iso8601Format.setTimeZone(TimeZone.getTimeZone("UTC")); + return iso8601Format; + } + + public static final TypeAdapter DATE = new TypeAdapter() { + private final DateFormat enUsFormat = + DateFormat.getDateTimeInstance(DateFormat.DEFAULT, DateFormat.DEFAULT, Locale.US); + private final DateFormat localFormat = + DateFormat.getDateTimeInstance(DateFormat.DEFAULT, DateFormat.DEFAULT); + private final DateFormat iso8601Format = buildIso8601Format(); + @Override + public Date read(JsonReader reader) throws IOException { + return deserializeToDate(reader.nextString()); + } + + private Date deserializeToDate(String json) { + synchronized (localFormat) { + try { + return localFormat.parse(json); + } catch (ParseException ignored) { + } + try { + return enUsFormat.parse(json); + } catch (ParseException ignored) { + } + try { + return iso8601Format.parse(json); + } catch (ParseException e) { + throw new JsonSyntaxException(json, e); + } + } + } + + @Override + public void write(JsonWriter writer, Date value) throws IOException { + synchronized (localFormat) { + String dateFormatAsString = enUsFormat.format(value); + writer.value(dateFormatAsString); + } + } + }; + + public static final TypeAdapter.Factory DATE_FACTORY = newFactory(Date.class, DATE); + public static final TypeAdapter.Factory UUID_FACTORY = newFactory(UUID.class, UUID); public static final TypeAdapter