2015-07-10 50 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 –