当前位置: 首页 > 知识库问答 >
问题:

Java语言时间总体安排无法在索引0处分析DateTimeParseException

江衡
2023-03-14

我试图告诉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();

共有1个答案

巫新知
2023-03-14

正如@Jon Skeet在评论中所说,与输入字符串相比,您的模式有1个额外的数字,因此YYMMDDHHMMSSSS无法工作:输入有16个数字,而模式YYMMDDHHMMSSSS需要17个数字。

虽然最后一部分(0700)看起来像UTC偏移量,但它缺少一个符号(因此应该是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个零视为秒的分数。

在这种情况下,由于Java 8 API中的错误,诸如YYYYMMDDHHMMSSS之类的模式将无法工作。

上面的相同链接还提供了解决方法:使用java。时间总体安排带有java的DateTimeFormatterBuilder。时间世俗的计时字段(以秒为单位)。

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

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

 类似资料: