You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何修改DateTimeFormatter的minWidth会引发解析异常?

为什么修改appendFraction的minWidth会导致DateTimeFormatter解析失败?

我在Java 21中遇到一个问题:两个DateTimeFormatter配置几乎完全一致,仅修改了appendFraction的minWidth参数,其中第二个就抛出了解析异常,两种模式看起来都合法,请问原因是什么?

可正常运行的代码

输出为{},ISO resolved to 2024-12-31T23:59:59.123:

var result1 = new DateTimeFormatterBuilder()
        .appendPattern("yyyyMMddHHmmss")
        .appendFraction(ChronoField.NANO_OF_SECOND, 3, 3, false) // minWidth 为3
        .toFormatter()
        .parse("20241231235959123");
System.out.println(result1);

抛出异常的代码

var result2 = new DateTimeFormatterBuilder()
        .appendPattern("yyyyMMddHHmmss")
        .appendFraction(ChronoField.NANO_OF_SECOND, 1, 3, false) // minWidth 为1
        .toFormatter()
        .parse("20241231235959123");
System.out.println(result2);

异常信息

Exception in thread "main" java.time.format.DateTimeParseException: Text '20241231235959123' could not be parsed at index 0
    at java.base/java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:2108)
    at java.base/java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1936)
    at Main.main(Main.java:24)

原因解析

问题出在appendFraction方法的参数行为逻辑上:

  • 当minWidth和maxWidth相等时(如第一个例子的3和3),即使decimalSeparatorIgnored设为false,解析器会直接读取对应固定长度的数字作为纳秒部分,不需要小数点分隔。
  • 当minWidth < maxWidth时(如第二个例子的1和3),decimalSeparatorIgnored = false会强制要求解析时必须先出现小数点,再匹配小数部分。但你的输入字符串里没有小数点,导致解析器从索引0开始就无法匹配预期格式,直接抛出异常。

解决办法

如果要让第二个配置正常解析无小数点的输入,有两种方案:

  1. 将decimalSeparatorIgnored改为true,允许解析器忽略小数点,直接读取1-3位数字作为纳秒:
var result2 = new DateTimeFormatterBuilder()
        .appendPattern("yyyyMMddHHmmss")
        .appendFraction(ChronoField.NANO_OF_SECOND, 1, 3, true)
        .toFormatter()
        .parse("20241231235959123");
  1. 修改输入字符串,添加小数点分隔,例如20241231235959.123。

内容的提问来源于stack exchange,提问作者Steven

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 23:29:50