使用SimpleDateFormat的Gson转换器

时间:2015-07-10 13:59:05

标签: gson simpledateformat

我正在运行一个使用带有简单日期格式功能的Gson Converter的代码,偶尔日期格式化会使它显示日期在1969-1970,具体取决于时区或它需要它并显示一些随机日期。

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'"};

2 个答案:

答案 0 :(得分:4)

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

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

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

答案 1 :(得分:0)

setLenient可能会导致它以奇怪的方式解析日期,具体取决于确切的格式。对您接受的格式进行更严格的处理可能会更好,并使setLenient保持为假。