如何使用Jackson反序列化JS日期?

Var*_*har 67 java datetime json jackson

我从ExtJS获得一个日期字符串格式:

"2011-04-08T09:00:00"

当我尝试反序列化此日期时,它会将时区更改为印度标准时间(将时间+5:30添加).这就是我如何反序化日期:

SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
getObjectMapper().getDeserializationConfig().setDateFormat(dateFormat);
Run Code Online (Sandbox Code Playgroud)

这样做也不会改变时区.我仍然在IST得到日期:

SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
dateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
getObjectMapper().getDeserializationConfig().setDateFormat(dateFormat);
Run Code Online (Sandbox Code Playgroud)

如何在没有时区麻烦的情况下对日期的日期进行反序列化?

Var*_*har 136

我找到了一个解决方法但是我需要在整个项目中注释每个日期的setter.有没有一种方法可以在创建ObjectMapper时指定格式?

这是我做的:

public class CustomJsonDateDeserializer extends JsonDeserializer<Date>
{
    @Override
    public Date deserialize(JsonParser jsonParser,
            DeserializationContext deserializationContext) throws IOException, JsonProcessingException {

        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
        String date = jsonParser.getText();
        try {
            return format.parse(date);
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }

    }

}
Run Code Online (Sandbox Code Playgroud)

并使用以下方法注释每个Date字段的setter方法:

@JsonDeserialize(using = CustomJsonDateDeserializer.class)
Run Code Online (Sandbox Code Playgroud)

  • 'T'的格式是因为这是使用ISO 8601标准的日期时间格式.显然,您不需要使用ISO标准格式,但在使用ExtJS等第三方库时,它可以提高兼容性.http://en.wikipedia.org/wiki/ISO_8601#Combined_date_and_time_representations (8认同)
  • @jjb不,这是真的错了.由于simpleDateFormatter不是线程安全的,并且当jackons缓存根级反序列化器(并且不能禁用它)时,你必须为每个日期使用不同的SimpleDateFormatter作为Varun Achar的提议或者同步deserialize方法是你使用一个字段SimpleDateFormatter.而这个领域不可能是静态的.这是我见过的最糟糕的虫子之一. (7认同)

小智 55

这对我有用 - 我使用的是杰克逊2.0.4

ObjectMapper objectMapper = new ObjectMapper();
final DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
objectMapper.setDateFormat(df);
Run Code Online (Sandbox Code Playgroud)

  • 或者代替SimpleDateFormat,我使用新的ISO8601DateFormat(),它与大多数其他语言的默认值(C#,Ruby等)一致. (10认同)
  • 是否已弃用setDateFormat? (3认同)
  • 我是杰克逊的新手,我想知道在哪里添加上面的代码? (2认同)
  • 'objectMapper.setDateFormat(DF);' 如果你只有一个实用工具或一个你设置格式的唯一bean,那就好了,否则你总是要记住在你使用它的地方设置它.此外,DateFormat不是线程安全的! (2认同)

wan*_*ngf 13

有一个关于这个主题的好博客:http: //www.baeldung.com/jackson-serialize-dates 使用@JsonFormat看起来是最简单的方法.

public class Event {
    public String name;

    @JsonFormat
      (shape = JsonFormat.Shape.STRING, pattern = "dd-MM-yyyy hh:mm:ss")
    public Date eventDate;
}
Run Code Online (Sandbox Code Playgroud)

  • 这是用于序列化而不是反序列化? (3认同)

Tim*_*the 6

除了Varun Achar的回答之外,这是我提出的Java 8变体,它使用java.time.LocalDate和ZonedDateTime而不是旧的java.util.Date类.

public class LocalDateDeserializer extends JsonDeserializer<LocalDate> {

    @Override
    public LocalDate deserialize(JsonParser jsonparser, DeserializationContext deserializationcontext) throws IOException {

        String string = jsonparser.getText();

        if(string.length() > 20) {
            ZonedDateTime zonedDateTime = ZonedDateTime.parse(string);
            return zonedDateTime.toLocalDate();
        }

        return LocalDate.parse(string);
    }
  }
Run Code Online (Sandbox Code Playgroud)

  • 您可以配置和使用Jackson的[JSR-310数据类型模块](https://github.com/FasterXML/jackson-datatype-jsr310),而不是编写自己的解串器. (2认同)