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

无法在索引0处分析java.time.format.DateTimeParseException,java,gson,java-time,datetime-parsing,localdate,Java,Gson,Java Time,Datetime Parsing,Localdate,我试图告诉Gson如何解析LocalDateTime和LocalDate,但是我得到了这个错误,在我看来它应该与格式匹配。我在想,要么是关于解析日期我不了解,要么是关于Gson我不了解 java.time.format.DateTimeParseException:无法在索引0处分析文本“2017101800000700” Gson Gson=new GsonBuilder().registerTypeAdapter(LocalDateTime.class,new JsonDeserialize

我试图告诉Gson如何解析
LocalDateTime
LocalDate
,但是我得到了这个错误,在我看来它应该与格式匹配。我在想,要么是关于解析日期我不了解,要么是关于Gson我不了解

java.time.format.DateTimeParseException:无法在索引0处分析文本“2017101800000700”

Gson Gson=new GsonBuilder().registerTypeAdapter(LocalDateTime.class,new JsonDeserializer()){ @凌驾 公共LocalDateTime反序列化(JsonElement json,类型,JsonDeserializationContext JsonDeserializationContext)引发JsonParseException{ 返回LocalDateTime.parse(json.getAsJsonPrimitive().getAsString(),DateTimeFormatter.of模式(“yyyymmddhhmmssss”); } }).registerTypeAdapter(LocalDate.class,新的JsonDeserializer()){ @凌驾 公共LocalDate反序列化(JsonElement json,类型类型,JsonDeserializationContext JsonDeserializationContext)引发JsonParseException{ 返回LocalDate.parse(json.getAsJsonPrimitive().getAsString(),DateTimeFormatter.of模式(“yyyyMMdd”); } }).create(); 与输入字符串相比,您的模式有1个额外的数字,因此
yyymmddhhmmssss
将不起作用:输入
2017101800000700
有16个数字,而模式
yyyymmddhhmmssss
需要17个数字


虽然最后一部分(
0700
)看起来像一个符号,但它缺少一个
+
-
符号(因此它应该是
+0700
-0700
)。偏移量表示与UTC的差异,如果没有符号,它是不明确的:您不能说它是在UTC之前还是之后

即使它真的是一个偏移量,我也找不到一种没有符号的解析方法:我尝试了,但没有一个有效。符号始终是必需的,因此不可能将其解析为偏移量,除非您做出任意假设(例如“它是正的”)并手动更改输入,如下所示:

// 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
这将导致
LocalDateTime
等于:

2017-10-18T00:00


另一种方法是将
07
视为秒,将最后2个零视为秒的分数

在这种情况下,诸如
yyyymmddhhmmsss
之类的模式将由于错误而无法工作

上面的同一链接还提供了解决方法:使用
java.time.format.DateTimeFormatterBuilder
java.time.temporal.ChronoField
以几秒钟为单位

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
这将分析以下
LocalDateTime

2017-10-18T00:00:07


请注意,它与前一个不同,因为现在我们考虑将
07
作为秒。

好的2017101800000700不适合YYYYMMDDHHMMSSSS-您没有足够的数字。(在日期之后,有00000700,HHMMS为000007,SSS只剩下00。)但我怀疑0700实际上是UTC的时区偏移。@JonSkeet唯一奇怪的事情(如果0700是偏移)是缺少
+
-
符号,所以它是一个模糊的偏移。或者没有符号表示肯定?@Hugo:同意,这很奇怪。
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