datetimeformatter.iso_local_date 仅解析“yyyy-mm-dd”格式纯日期字符串,不接受时间、时区、空格或非短横线分隔符;其模式严格为uuuu-mm-dd,月份和日期必须两位补零,任何偏差均抛datetimeparseexception。

DateTimeFormatter.ISO_LOCAL_DATE 只能解析形如 "2023-10-05" 的纯日期字符串,不接受带时间、时区或多余空格的输入——这是它和 ISO_DATE 最关键的区别。
为什么 parse("2023-10-05 14:30") 会抛 DateTimeParseException
因为 ISO_LOCAL_DATE 的模式是 uuuu-MM-dd,严格匹配三位数字年、两位月、两位日,中间只允许短横线。任何额外字符(包括空格、冒号、T、Z)都会导致解析失败。
- ✅ 成功:
"2023-04-01"、"2020-12-31" - ❌ 失败:
"2023-04-01T10:30"(多了T和时间)、" 2023-04-01 "(首尾空格)、"2023/04/01"(斜杠非短横线) - ⚠️ 注意:
"2023-4-1"也会失败——月份和日期必须补零为两位
如何安全地用 ISO_LOCAL_DATE 解析用户输入
实际场景中用户可能多输空格或混用分隔符,不能直接硬套 ISO_LOCAL_DATE。推荐先清洗再解析:
- 用
String.trim()去首尾空格 - 用正则
replaceAll("[^\d\-]", "")粗略过滤非法字符(慎用,仅限可信来源) - 更稳妥的做法:用
DateTimeFormatter.ofPattern("yyyy-MM-dd")替代,它行为一致但可读性更高,且便于后续扩展 - 务必包在
try-catch中捕获DateTimeParseException,不要让异常穿透业务逻辑
ISO_LOCAL_DATE vs ISO_DATE:选哪个?
两者都来自 DateTimeFormatter 静态常量,但语义不同:
-
ISO_LOCAL_DATE→ 仅日期,类型返回LocalDate,无时区、无时间信息 -
ISO_DATE→ 支持"2023-10-05"、"2023-10-05+01"、"2023-10-05Z",返回OffsetDate,带偏移量 - 如果你明确只要日期部分,且输入可控,用
ISO_LOCAL_DATE更精准;如果输入可能含时区且你仍想解析日期部分,ISO_DATE会更宽容
真正容易被忽略的是:ISO_LOCAL_DATE 不做任何宽松处理,哪怕一个不可见的 u200b 零宽空格也会让它静默失败——所以生产环境建议始终校验输入长度和字符集,别只依赖格式器兜底。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











