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

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

白智
2023-03-14

这看起来是一件很简单的事情,但我没有做到。

我有一个字符串模式,它是yyyyMMddHH,我试图将其解析为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,但这没有帮助。

为什么我会有这个例外?如何解决这个问题?

编辑:

我无法删除。parseDefaulting(ChronoField.HOUR\u OF\u DAY,0)

以下是限制条件:

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

使用这些约束,我无法删除. parseDefaulting(ChronoField.HOUR_OF_DAY,0),因为如果我这样做,我将无法将yyyy-MM-dd解析为LocalDateTime的实例

共有1个答案

陆昂然
2023-03-14

好吧,我认为这是由. parseDefaulting(ChronoField.HOUR_OF_DAY,0)行引起的。构建器会在进行任何解析之前立即插入默认值。在解析时,小时组件已经有一个值,因此HH的解析失败。

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();

这是一个将这些行移动到构建器末尾的工作示例

 类似资料: