Java 17解析两位小数时间失败,Java 8正常的原因咨询
Java 8与Java 17中DateTimeFormatter解析差异原因分析
问题重现
以下代码在Java 8中可正常执行,但在Java 17中抛出解析异常:
import java.time.OffsetDateTime; import java.time.format.DateTimeFormatter; public class Main2 { public static void main(String[] args) { DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH[:mm[:ss[.SSS]]]X"); OffsetDateTime offSetDateTime = OffsetDateTime.parse("2021-10-09T08:59:00.00Z", formatter); System.out.println(offSetDateTime); } }
Java 17运行异常
Exception in thread "main" java.time.format.DateTimeParseException: Text '2021-10-09T08:59:00.00Z' could not be parsed at index 19 at java.base/java.time.format.DateTimeFormatter.parseResolved0(DateTimeFormatter.java:2052) at java.base/java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1954) at java.base/java.time.OffsetDateTime.parse(OffsetDateTime.java:404) at Main2.main(Main2.java:9)
Java 8运行输出
2021-10-09T08:59Z
将输入字符串改为"2021-10-09T08:59:00.000Z"(毫秒部分补为3位),Java 17即可正常运行。
差异原因
这个问题源于Java 9及后续版本(包括Java 17)对DateTimeFormatter中SSS模式的解析规则做了严格化调整:
- Java 8行为:
SSS表示毫秒数,支持解析1-3位的毫秒值,不足3位时会自动补零处理,因此.00会被识别为000毫秒。 - Java 9+行为:
SSS被严格限定为必须匹配3位数字,当输入只有2位毫秒(.00)时,直接触发格式不匹配的解析异常。
兼容解决方案
如果需要兼容不同位数的毫秒输入,可将格式模式中的SSS改为S:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH[:mm[:ss[.S]]]X");
S模式可以匹配1-9位的秒小数部分,无论输入是1位、2位还是3位毫秒,Java 8和Java 17都能正常解析。
内容的提问来源于stack exchange,提问作者Starbucks Admin
相关产品推荐
相关产品推荐

