另一种方法是创建自定义反序列化程序。首先,您注释相应的字段:
@JsonDeserialize(using = OffsetDateTimeDeserializer.class)
private OffsetDateTime date;
然后你创建反序列化器。它使用java.time.format.DateTimeFormatterBuilder,使用大量可选部分来处理所有不同类型的偏移:
public class OffsetDateTimeDeserializer extends JsonDeserializer<OffsetDateTime> {
private DateTimeFormatter fmt = new DateTimeFormatterBuilder()
// date/time
.append(DateTimeFormatter.ISO_LOCAL_DATE_TIME)
// offset (hh:mm - "+00:00" when it's zero)
.optionalStart().appendOffset("+HH:MM", "+00:00").optionalEnd()
// offset (hhmm - "+0000" when it's zero)
.optionalStart().appendOffset("+HHMM", "+0000").optionalEnd()
// offset (hh - "+00" when it's zero)
.optionalStart().appendOffset("+HH", "+00").optionalEnd()
// offset (pattern "X" uses "Z" for zero offset)
.optionalStart().appendPattern("X").optionalEnd()
// create formatter
.toFormatter();
@Override
public OffsetDateTime deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
return OffsetDateTime.parse(p.getText(), fmt);
}
}
我还使用了内置常量DateTimeFormatter.ISO_LOCAL_DATE_TIME,因为它处理了可选的秒数小数部分——而且小数位数似乎也是可变的,而且这个内置格式化程序已经处理了这些细节给你。
我正在使用 JDK 1.8.0_144 并找到了一个更短(但不多)的解决方案:
private DateTimeFormatter fmt = new DateTimeFormatterBuilder()
// date/time
.append(DateTimeFormatter.ISO_LOCAL_DATE_TIME)
// offset +00:00 or Z
.optionalStart().appendOffset("+HH:MM", "Z").optionalEnd()
// offset +0000, +00 or Z
.optionalStart().appendOffset("+HHmm", "Z").optionalEnd()
// create formatter
.toFormatter();
您可以进行的另一项改进是将格式化程序更改为static final、because this class is immutable and thread-safe。