Gson: GSON default date serializer is locale-specific

Created on 19 Mar 2015  路  15Comments  路  Source: google/gson

This has caused problems for Caliper, which was relying on the default date 
serializer:
http://code.google.com/p/caliper/issues/detail?id=113

Work-around the problem by registering a date type adapter like the following:

  private static class DateTypeAdapter implements JsonSerializer<Date>, JsonDeserializer<Date> {
    private final DateFormat dateFormat;

    private DateTypeAdapter() {
      dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssz", Locale.US);
      dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
    }

    @Override public synchronized JsonElement serialize(Date date, Type type,
        JsonSerializationContext jsonSerializationContext) {
      return new JsonPrimitive(dateFormat.format(date));
    }

    @Override public synchronized Date deserialize(JsonElement jsonElement, Type type,
        JsonDeserializationContext jsonDeserializationContext) {
      try {
        return dateFormat.parse(jsonElement.getAsString());
      } catch (ParseException e) {
        throw new JsonParseException(e);
      }
    }
  }

Original issue reported on code.google.com by limpbizkit on 30 Jan 2011 at 1:01

Priority-Medium Type-Defect auto-migrated

Most helpful comment

All 15 comments

Fixed by r721.

Original comment by limpbizkit on 10 Feb 2011 at 1:07

  • Changed state: Fixed
It will be great if we can configure GsonBuilder to force used of ISO-8601 
format with UTC timezone, for serialization and deserialization.

Thanks

Original comment by [email protected] on 14 Jun 2011 at 10:03

[deleted comment]
private static class GmtDateTypeAdapter implements JsonSerializer<Date>, 
JsonDeserializer<Date> {
        private final DateFormat dateFormat;

        private GmtDateTypeAdapter() {
            dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US);
            dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
        }

        @Override
        public synchronized JsonElement serialize(Date date, Type type,
                JsonSerializationContext jsonSerializationContext) {
            synchronized (dateFormat) {
                String dateFormatAsString = dateFormat.format(date);
                return new JsonPrimitive(dateFormatAsString);
            }
        }

        @Override
        public synchronized Date deserialize(JsonElement jsonElement, Type type,
                JsonDeserializationContext jsonDeserializationContext) {
            try {
                synchronized (dateFormat) {
                    return dateFormat.parse(jsonElement.getAsString());
                }
            } catch (ParseException e) {
                throw new JsonSyntaxException(jsonElement.getAsString(), e);
            }
        }
    }

Original comment by [email protected] on 14 Jun 2011 at 12:36

+1 ! And it would be nice to be able to specify the DateFormat and not just 
only the SDF pattern on the GsonBuilder

Original comment by [email protected] on 15 Mar 2013 at 2:46

Which version of gson has this fix ?

Original comment by [email protected] on 3 Jul 2014 at 9:48

still experiencing this issue in gson 2.3.1

This issue still exists in Gson 2.4

Is the intention that the UtcDateTypeAdapter introduced in 2.4 should be manually registered as a type adapter?

@code77se Yes. Register UtcDateTypeAdapter manually.

Still an issue in gson 2.7

import com.google.gson.typeadapters.UtcDateTypeAdapter;

Error:

error: package com.google.gson.typeadapters does not exist
import com.google.gson.typeadapters.UtcDateTypeAdapter;

Worked as:

Gson gson = new GsonBuilder()
        .setPrettyPrinting()
        .setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSX")
        .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
        .create();

@Paxa
this only adds hour difference. but for countries like India you will miss the minutes part.
Instead of X use Z to get the minutes part as well
java Gson gson = new GsonBuilder() .setPrettyPrinting() .setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ") .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES) .create();

This will be slightly off topic still I hope you can help me. For my applications I get strings like "2017-10-13T18:10+03:00", "2017-10-13T14:15+02:00", etc. which have to be converted to a java.util.Date property without loosing time zone information.

I'm using new GsonBuilder().setDateFormat("yyyy-MM-dd'T'HH:mm:ssX").create()
already which leads to correct date/time but converted to my time zone and the original time zone property of the Date being lost.

How can I convert the String to Date while maintaining the time zone information?

Thanks!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

GoogleCodeExporter picture GoogleCodeExporter  路  32Comments

danieleguiducci picture danieleguiducci  路  34Comments

GoogleCodeExporter picture GoogleCodeExporter  路  25Comments

LucianWang picture LucianWang  路  42Comments

RobMans426 picture RobMans426  路  20Comments