为何Java DateTimeFormatter无法解析模式'ddMyyyy'的日期字符串?
问题:SimpleDateFormat与DateTimeFormatter解析日期字符串的差异
给定日期字符串与匹配模式:
String date = "2391995"; String patt = "ddMyyyy";
根据模式ddMyyyy,该字符串代表1995年9月23日(23日、9月、1995年)。
两种解析实现代码
// 旧方式:使用SimpleDateFormat Date dd = new SimpleDateFormat(patt).parse(date); System.out.println(dd); // Java 8+方式:使用DateTimeFormatter + LocalDate DateTimeFormatter formatter = DateTimeFormatter.ofPattern(patt); LocalDate d = LocalDate.parse(date, formatter); System.out.println(d);
执行输出结果
Sat Sep 23 00:00:00 EDT 1995 Exception in thread "main" java.time.format.DateTimeParseException: Text '2391995' could not be parsed at index 7 ...
差异原因
两者核心差异在于解析逻辑的严格性和匹配策略:
- SimpleDateFormat采用宽松试探模式:它会尝试多种拆分方式适配模式,只要能组合出合法日期就成功。解析
2391995时,它先取前两位23作为日期,接着取1位9作为合法月份(9月),最后剩下的1995刚好是4位年份,完全符合规则,因此解析成功。 - DateTimeFormatter默认采用严格贪婪匹配模式:它解析时会尽可能读取连续数字匹配对应模式段,且不允许自动回退重试。遇到
M(月份)时,它会从日期后的位置开始读取连续数字,先尝试读取91作为月份,但91超出了合法月份范围(1-12),严格模式下不会回退尝试只读1位9;后续读取4位年份时,剩余字符串长度不足,最终抛出解析异常。
如果要让DateTimeFormatter成功解析该字符串,可以设置宽松解析模式:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(patt) .withResolverStyle(ResolverStyle.LENIENT); LocalDate d = LocalDate.parse(date, formatter); System.out.println(d); // 输出:1995-09-23
内容的提问来源于stack exchange,提问作者Twisted Tea
相关产品推荐
相关产品推荐

