我想告诉Gson如何解析LocalDateTime
和LocalDate
,但是我收到了这个错误,我觉得它应该与格式匹配。我在想是解析日期或者我对Gson不了解的事情,我不明白。
java.time.format.DateTimeParseException:无法在索引0处解析文本“2017101800000700”
Gson gson = new GsonBuilder().registerTypeAdapter(LocalDateTime.class, new JsonDeserializer<LocalDateTime>() {
@Override
public LocalDateTime deserialize(JsonElement json, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException {
return LocalDateTime.parse(json.getAsJsonPrimitive().getAsString(), DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS"));
}
}).registerTypeAdapter(LocalDate.class, new JsonDeserializer<LocalDate>() {
@Override
public LocalDate deserialize(JsonElement json, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException {
return LocalDate.parse(json.getAsJsonPrimitive().getAsString(), DateTimeFormatter.ofPattern("yyyyMMdd"));
}
}).create();
答案 0 :(得分:2)
作为@Jon Skeet said in the comments,与输入字符串相比,您的模式有1个额外数字,因此yyyyMMddHHmmssSSS
将不起作用:输入2017101800000700
有16位数,而模式{{ 1}}期待17。
虽然最后一部分(yyyyMMddHHmmssSSS
)看起来像UTC offset,但它缺少0700
或+
符号(因此它应该是-
或{ {1}})。偏移代表与UTC的差异,没有符号,它是不明确的:你不能说它是在UTC之前还是之后。
即使它真的是一个偏移量,我找不到一种没有符号解析的方法:我试过all the available options但没有一个工作。总是需要一个符号,因此无法将其解析为偏移量,除非您做出任意假设(例如“它是肯定的”)并手动更改输入,像这样:
+0700
这将导致-0700
等于:
2017-10-18T00:00
另一种选择是将// assuming the offset "0700" is positive (7 hours ahead UTC)
String dateStr = "2017101800000700";
// insert the "+" manually, so input becomes 201710180000+0700
dateStr = dateStr.substring(0, 12) + "+" + dateStr.substring(12, 16);
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyyMMddHHmmXX");
System.out.println(LocalDateTime.parse(dateStr, fmt)); // 2017-10-18T00:00
视为秒,将最后2个零视为秒的分数。
在这种情况下,由于bug in Java 8 API,LocalDateTime
等模式将无效。
上面的相同链接也提供了解决方法:使用07
和yyyyMMddHHmmssSS
的秒数。
java.time.format.DateTimeFormatterBuilder
这将解析以下java.time.temporal.ChronoField
:
2017-10-18T00:00:07
请注意,它与前一个不同,因为现在我们正在考虑将String dateStr = "2017101800000700";
DateTimeFormatter fmt = new DateTimeFormatterBuilder()
// date/time
.appendPattern("yyyyMMddHHmmss")
// milliseconds (with 2 digits)
.appendValue(ChronoField.MILLI_OF_SECOND, 2)
// create formatter
.toFormatter();
System.out.println(LocalDateTime.parse(dateStr, fmt)); // 2017-10-18T00:00:07
作为秒。