2015-07-10 51 views
3

我正在运行一个代码,使用Gson转换器与简单的日期格式功能,并在一段时间内,日期格式化是弄乱无论是显示日期早在1969年至1970年取决于时区或它需要它并显示一些随机日期。Gson转换器与SimpleDateFormat

static class DateSerializer implements JsonDeserializer<Date> { 
    @Override 
    public Date deserialize(JsonElement jsonElement, Type typeOF, JsonDeserializationContext context) 
      throws JsonParseException { 
     for (SimpleDateFormat simpleDateFormat : DATE_FORMATS) { 
      try { 
       simpleDateFormat.setLenient(true); 

       return simpleDateFormat.parse(jsonElement.getAsString()); 
      } catch (ParseException e) { 
      } 
     } 
     return null; 
    } 
} 
static { 
    final TimeZone GMT_TIMEZONE = TimeZone.getTimeZone("GMT"); 
    int i = 0; 
    for (String format : DATE_FORMAT_STRINGS) { 
     SimpleDateFormat dateFormat = new SimpleDateFormat(format, Locale.US); 
     dateFormat.setTimeZone(GMT_TIMEZONE); 
     DATE_FORMATS[i++] = dateFormat; 
    } 
} 
Gson gson = new GsonBuilder() 
      .registerTypeAdapter(Date.class, new DateSerializer()) 
      .create(); 
private static final String[] DATE_FORMAT_STRINGS = new String[]{"yyyy-MM-dd'T'HH:mm:ssZZZZ", 
                   "yyyy-MM-dd'T'HH:mm:ss'Z'"}; 

回答

0

setLenient可能导致它在解析一个奇怪的方式日期,根据确切的格式。对接受的格式更严格,并保持setLenient为假。

+0

问题仍然发生没有setLenient –

4

问题是SimpleDateFormat is not thread-safe。您的反序列化在多个线程中发生以提高性能,但由于SimpleDateFormat的非线程安全性,您偶尔会在解析日期中回收垃圾。

解决此问题的两种方法是在每次需要时创建一个新的SimpleDateFormat,或者通过执行诸如在日期格式上创建锁定等操作来强制执行原子操作。

例如,GSON的DefaultDateTypeAdapter采用后一种方法。

+0

与dateFormat我如何使它采取特定格式? “yyyy-MM-dd'T'HH:mm:ssZZZZ” –

+0

你不需要使用'DateFormat'-我只是继续使用'SimpleDateFormat'。 'SimpleDateFormat'无论如何都是'DateFormat'的一个子类。 –

+0

这是正确的答案。我自己也经历过同样的随机日期问题,并追踪到这个问题。另一个解决方法是为每个线程创建SimpleDateFormat的实例 - 如此处所示:http://stackoverflow.com/a/817926/1666063 –