有时你应该反序列化字符串,如" 2018-05-15T09:27:00.65530782Z"这可能看起来像:
然后尝试将DateTimeFormatterBuilder与optionalStart()/ optionalEnd()方法一起使用:
public class CustomDateTimeDeserializer extends JsonDeserializer<ZonedDateTime> {
private DateTimeFormatter fmt = new DateTimeFormatterBuilder()
.parseCaseInsensitive()
.appendPattern("yyyy-MM-dd'T'HH:mm")
.optionalStart()
.appendLiteral(":")
.appendFraction(ChronoField.SECOND_OF_MINUTE, 0, 2, false)
.optionalEnd()
.optionalStart()
.appendLiteral(".")
.optionalEnd()
.optionalStart()
.appendFraction(ChronoField.NANO_OF_SECOND, 0, 9, false)
.optionalEnd()
.optionalStart()
.appendLiteral("Z")
.optionalEnd()
.toFormatter();
@Override
public ZonedDateTime deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
return ZonedDateTime.of(LocalDateTime.from(fmt.parse(p.getText())), ZoneId.of("UTC"));
}
}
答案 0 :(得分:1)
如果您的复杂格式化程序不起作用,另一种方法是填充用零和任何标点符号传递的值,以便始终具有相同的格式。然后,转换那个。
答案 1 :(得分:0)
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.append(DateTimeFormatter.ISO_LOCAL_DATE_TIME)
.optionalStart()
.appendPattern("XXX")
.optionalEnd()
.parseDefaulting(ChronoField.OFFSET_SECONDS, 0)
.toFormatter();
String[] inputs = {
"2018-05-15T09:27:00.65530Z",
"2018-05-15T09:27:00",
"2018-05-15T09:27",
"2018-06-12T15:35:01.2344+01:00"
};
for (String input : inputs) {
System.out.println(OffsetDateTime.parse(input, formatter));
}
输出:
2018-05-15T09:27:00.655300Z
2018-05-15T09:27Z
2018-05-15T09:27Z
2018-06-12T15:35:01.234400+01:00
如果我正确阅读了您的要求,则有两个独立的问题:
ISO_LOCAL_DATE_TIME
处理它。格式化程序可以嵌套,所以我们只需将它附加到我们自己的fomatter上。Z
意味着UTC偏移零)。在这里,我使用一个可选部分与parseDefaulting
结合使用,以提供在没有偏移时使用的值。正如Ivan在a comment中所说,处理不同小数的另一种方法可能是DateTimeFormatterBuilder.appendFraction
。
为偏移量(XXX
)指定模式而不是坚持匹配文字Z
,我们也可以解析其他偏移量,就像上一个输入示例所示。