无法在索引0处解析java.time.format.DateTimeParseException

时间:2017-10-23 21:46:10

标签: java gson java-time datetime-parsing localdate

我想告诉Gson如何解析LocalDateTimeLocalDate,但是我收到了这个错误,我觉得它应该与格式匹配。我在想是解析日期或者我对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();

1 个答案:

答案 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 APILocalDateTime等模式将无效。

上面的相同链接也提供了解决方法:使用07yyyyMMddHHmmssSS的秒数。

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 作为秒。

相关问题