Java Date to UTC using gson

后端 未结 4 422
死守一世寂寞
死守一世寂寞 2020-12-05 00:04

I can\'t seem to get gson to convert a Date to UTC time in java.... Here is my code...

Gson gson = new GsonBuilder().setDateFormat(\"yyyy-MM-dd\'T\'HH:mm:ss.         


        
相关标签:
4条回答
  • 2020-12-05 00:19

    After some further research, it appears this is a known issue. The gson default serializer always defaults to your local timezone, and doesn't allow you to specify the timezone. See the following link.....

    https://code.google.com/p/google-gson/issues/detail?id=281

    The solution is to create a custom gson type adaptor as demonstrated in the link:

    // this class can't be static
    public class GsonUTCDateAdapter implements JsonSerializer<Date>,JsonDeserializer<Date> {
    
        private final DateFormat dateFormat;
    
        public GsonUTCDateAdapter() {
          dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.US);      //This is the format I need
          dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));                               //This is the key line which converts the date to UTC which cannot be accessed with the default serializer
        }
    
        @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);
          }
        }
    }
    

    Then register it as follows :

      Gson gson = new GsonBuilder().registerTypeAdapter(Date.class, new GsonUTCDateAdapter()).create();
      Date now=new Date();
      System.out.println(gson.toJson(now));
    

    This now correctly outputs the Date in UTC

    "2014-09-25T17:21:42.026Z"
    

    Thanks go to the link author.

    0 讨论(0)
  • 2020-12-05 00:32

    I adapted the marked solution and parametrized the DateFormat:

    import com.google.gson.JsonDeserializationContext;
    import com.google.gson.JsonDeserializer;
    import com.google.gson.JsonElement;
    import com.google.gson.JsonParseException;
    import com.google.gson.JsonPrimitive;
    import com.google.gson.JsonSerializationContext;
    import com.google.gson.JsonSerializer;
    
    import java.lang.reflect.Type;
    import java.text.DateFormat;
    import java.text.ParseException;
    import java.util.Date;
    
    public class GsonDateFormatAdapter implements JsonSerializer<Date>, JsonDeserializer<Date> {
    
        private final DateFormat dateFormat;
    
        public GsonDateFormatAdapter(DateFormat dateFormat) {
            this.dateFormat = dateFormat;
        }
    
        @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);
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-05 00:38

    The solution that worked for me for this issue was to create a custom Date adapter (P.S be carefull so that you import java.util.Date not java.sql.Date!)

    public class ColonCompatibileDateTypeAdapter implements JsonSerializer<Date>, JsonDeserializer< Date> {
    private final DateFormat dateFormat;
    
    public ColonCompatibileDateTypeAdapter() {
      dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ") {
            @Override
            public StringBuffer format(Date date, StringBuffer toAppendTo, FieldPosition pos) {
                StringBuffer rfcFormat = super.format(date, toAppendTo, pos);
                return rfcFormat.insert(rfcFormat.length() - 2, ":");
            }
    
            @Override
            public Date parse(String text, ParsePosition pos) {
                if (text.length() > 3) {
                    text = text.substring(0, text.length() - 3) + text.substring(text.length() - 2);
                }
                return super.parse(text, pos);
            }
        };
    
    
    }
    
    @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);
      }
    }}
    

    and then use it while creating GSON object

    Gson gson = new GsonBuilder().registerTypeAdapter(Date.class, new ColonCompatibileDateTypeAdapter()).create();
    
    0 讨论(0)
  • 2020-12-05 00:40

    The Z in your dateformat is in single-quotes, it must be unquoted to be replaced by the actual timezone.

    Furthermore, if you want your date in UTC, convert it first.

    0 讨论(0)
提交回复
热议问题