为何修改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开始就无法匹配预期格式,直接抛出异常。
解决办法
如果要让第二个配置正常解析无小数点的输入,有两种方案:
- 将
decimalSeparatorIgnored改为true,允许解析器忽略小数点,直接读取1-3位数字作为纳秒:
var result2 = new DateTimeFormatterBuilder() .appendPattern("yyyyMMddHHmmss") .appendFraction(ChronoField.NANO_OF_SECOND, 1, 3, true) .toFormatter() .parse("20241231235959123");
- 修改输入字符串,添加小数点分隔,例如
20241231235959.123。
内容的提问来源于stack exchange,提问作者Steven
相关产品推荐
相关产品推荐

