【问题标题】:java.time.format.DateTimeParseException: Text could not be parsed at indexjava.time.format.DateTimeParseException:无法在索引处解析文本
【发布时间】:2021-07-21 15:52:43
【问题描述】:

这看起来是一件很容易实现的事情,但我没有这样做。

我有一个字符串模式 yyyyMMddHH,我正在尝试将 2021061104 解析为 LocalDateTime 的实例

代码如下:

import java.time.Duration;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.format.DateTimeParseException;
import java.time.temporal.ChronoField;
import java.time.temporal.ChronoUnit;


class Main {
    public static void main(String[] args) {
        String pattern = "yyyyMMddHH";
        String date = "2021061104";
        DateTimeFormatter formatter =
            new DateTimeFormatterBuilder()
                .parseDefaulting(ChronoField.HOUR_OF_DAY, 0)
                .parseDefaulting(ChronoField.MINUTE_OF_HOUR, 0)
                .parseDefaulting(ChronoField.SECOND_OF_MINUTE, 0)
                .parseLenient()
                .appendPattern(pattern)
                .toFormatter();
        LocalDateTime ldt = LocalDateTime.parse(date, formatter);
    }
}

它抛出这个异常:

Exception in thread "main" java.time.format.DateTimeParseException: Text '2021061104' could not be parsed at index 8
        at java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:1949)
        at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1851)
        at java.time.LocalDateTime.parse(LocalDateTime.java:492)
        at Main.main(Main.java:22)

无法解析输入中的HH 字段。
我查看了 javadoc here 但这没有帮助。

为什么会有这个异常?如何解决?

编辑:

我无法删除.parseDefaulting(ChronoField.HOUR_OF_DAY, 0)

以下是约束:

  • 用户将给patterndate(可能是args[0]args[1]
  • 模式必须始终包含日期(年月和日期)
  • pattern 中的时间是可选的,最多只能是小时。
  • 几个有效模式的示例是:yyyy-MM-dd HHyyyy MM dd

由于这些限制,我无法删除 .parseDefaulting(ChronoField.HOUR_OF_DAY, 0),因为如果这样做,我将无法将 yyyy-MM-dd 解析为 LocalDateTime here 的实例

【问题讨论】:

  • 为什么不只是DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
  • 这能回答你的问题吗? Parse date-only as LocalDateTime in Java 8
  • 您可以使用new DateTimeFormatterBuilder().appendPattern("yyyy-MM-dd[HH]").parseDefaulting(ChronoField.HOUR_OF_DAY, 0).toFormatter(); 格式的可选部分[]

标签: java java-time


【解决方案1】:

嗯,我认为这是由.parseDefaulting(ChronoField.HOUR_OF_DAY, 0) 引起的。在进行任何解析之前,构建器会立即插入默认值。在解析的时候,hour组件已经有值了,所以HH的解析失败。

the JavaDocs中实际上提到了这种行为:

在解析期间,会检查解析的当前状态。如果指定的字段没有关联值,因为此时还没有成功解析,则将指定的值注入到解析结果中。注入是立即的,因此字段-值对将对格式化程序中的任何后续元素可见。因此,此方法通常在构建器结束时调用。

强调我的。

因此,一个可能的解决方法是将parseDefaulting 行移动到格式化程序构建器的末尾:

DateTimeFormatter formatter = new DateTimeFormatterBuilder()
    .parseLenient()
    .appendPattern(pattern)
    .parseDefaulting(ChronoField.HOUR_OF_DAY, 0)
    .parseDefaulting(ChronoField.MINUTE_OF_HOUR, 0)
    .parseDefaulting(ChronoField.SECOND_OF_MINUTE, 0)
    .toFormatter();

Here is a working example 将这些行移到构建器的末尾。

【讨论】:

  • 感谢您的回答!我实际上无法删除 .parseDefaulting(ChronoField.HOUR_OF_DAY, 0) 让我用我拥有的约束来更新问题。
  • 嘿!在格式化程序末尾移动parseDefaulting() 行实际上起到了作用!这很奇怪,因为我认为它遵循 Builder 模式——但它看起来不像这样!谢谢,将此答案标记为已接受。
  • 并且不需要.parseDefaulting(ChronoField.MINUTE_OF_HOUR, 0).parseDefaulting(ChronoField.SECOND_OF_MINUTE, 0) .parseDefaulting(ChronoField.HOUR_OF_DAY, 0) 为他们完成这项工作。
猜你喜欢
  • 2017-12-09
  • 1970-01-01
  • 2021-12-23
  • 1970-01-01
  • 2020-06-25
  • 1970-01-01
  • 2018-04-04
  • 2018-12-12
  • 2020-02-16
相关资源
最近更新 更多