使用DateTimeFormatter多可选模式时的顺序规则及异常原因咨询
DateTimeFormatter可选模式的匹配顺序规则
这个问题的核心在于DateTimeFormatter对可选模式的匹配是按顺序进行的,一旦某个模式成功匹配了部分或全部文本,解析就会停止,不会再尝试后续的模式,而且默认情况下解析要求文本被完全消耗,这就是你遇到异常的原因。
为什么第一种顺序能正常工作?
看你的第一个格式化器:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("[yyyy-MM-dd HH:mm:ss][yyyy-MM-dd]");
- 解析
1991-01-28 00:00:00时,第一个可选模式yyyy-MM-dd HH:mm:ss会完全匹配整个文本,解析器消耗了所有字符,成功完成解析,后续模式不会被尝试。 - 解析
1991-01-28时,第一个模式无法匹配(文本长度不够),解析器会继续尝试第二个模式yyyy-MM-dd,刚好匹配整个文本,所以也能成功。
为什么调换顺序后会抛出异常?
再看第二个格式化器:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("[yyyy-MM-dd][yyyy-MM-dd HH:mm:ss]");
当你解析1991-01-28 00:00:00时,解析器会先尝试第一个可选模式yyyy-MM-dd——这个模式会匹配文本的前10个字符(1991-01-28),此时解析器认为这个模式已经匹配成功,就停止了解析流程。但文本还剩下 00:00:00没有被消耗,而默认的解析规则要求输入文本必须被完全解析,所以就抛出了DateTimeParseException,提示"unparsed text found at index 10"。
解决方案
要避免这种问题,你需要把更具体、更长的可选模式放在前面,让解析器先尝试匹配完整的、包含更多信息的格式,再尝试更短的格式。就像你第一个例子那样,把带时间的模式放在日期模式前面,这样长文本会被第一个模式完全匹配,短文本才会落到第二个模式。
另外,如果你的场景允许部分解析(比如只提取日期部分,忽略后面的时间),也可以通过调整解析器的配置来实现,比如使用DateTimeFormatterBuilder设置解析时不要求完全匹配,但这种方式需要更精细的控制,一般推荐优先调整可选模式的顺序。
内容的提问来源于stack exchange,提问作者Arun Xavier
相关产品推荐
相关产品推荐

