采用SimpleDataFormat的Gson转换器

采用SimpleDataFormat的Gson转换器,gson,simpledateformat,Gson,Simpledateformat,我正在运行一个使用Gson转换器的代码,该转换器具有简单的日期格式功能。有时,日期格式会出现混乱,要么根据时区显示1969-1970年的日期,要么显示随机日期 static class DateSerializer implements JsonDeserializer<Date> { @Override public Date deserialize(JsonElement jsonElement, Type typeOF, JsonDeserializationC

我正在运行一个使用Gson转换器的代码,该转换器具有简单的日期格式功能。有时,日期格式会出现混乱,要么根据时区显示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'"};
静态类DateSerializer实现JsonDeserializer{
@凌驾
公共日期反序列化(JsonElement JsonElement,类型typeOF,JsonDeserializationContext)
抛出JsonParseException{
for(SimpleDataFormat SimpleDataFormat:DATE_格式){
试一试{
SimpleDataFormat.setLenient(真);
返回SimpleDataFormat.parse(jsoneElement.getAsString());
}捕获(解析异常){
}
}
返回null;
}
}
静止的{
最终时区GMT_TimeZone=TimeZone.getTimeZone(“GMT”);
int i=0;
for(字符串格式:日期\格式\字符串){
SimpleDataFormat dateFormat=新的SimpleDataFormat(格式,Locale.US);
dateFormat.setTimeZone(GMT_时区);
日期格式[i++]=日期格式;
}
}
Gson Gson=new GsonBuilder()
.registerTypeAdapter(Date.class,新的DateSerializer())
.create();
私有静态最终字符串[]日期\格式\字符串=新字符串[]{“yyy-MM-dd'T'HH:MM:ssZZZZ”,
“yyyy-MM-dd'HH:MM:ss'Z'”;

setLenient可能会导致它以一种奇怪的方式解析日期,具体取决于具体的格式。最好对您接受的格式更加严格,并将
设置为false。

问题在于。您的反序列化正在跨多个线程进行以提高性能,但由于
SimpleDateFormat
的非线程安全性,您偶尔会在解析的日期中收到垃圾

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


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

如果没有setLenientwith dateFormat,问题仍然会发生。如何使其采用特定的格式?“yyyy-MM-dd'HH:MM:ssZZZZ”您不需要使用
DateFormat
-我只需要继续使用
SimpleDateFormat
SimpleDataFormat
DateFormat
的一个子类。这是正确的答案。我自己也经历过同样的随机日期问题,并一直追踪到这个问题。另一种解决方法是为每个线程创建SimpleDataFormat的实例,如这里所建议的