直接原因是日期字符串与SimpleDateFormat模式不匹配,需确保格式完全一致(含大小写、分隔符、位数等);注意y/Y、M/m、H/h、S/s、D/d等字母含义差异;时区处理推荐java.time新API;SimpleDateFormat非线程安全,应避免共享实例。

直接原因是日期字符串格式和 SimpleDateFormat 指定的模式不匹配,比如年份写成两位但模式用了 yyyy,或空格、中英文标点混用,或时区/毫秒等字段缺失。核心解决思路是:**确保字符串与 pattern 完全一致,包括大小写、分隔符、位数、甚至不可见字符**。
检查日期字符串和 pattern 是否严格一致
这是最常见原因。例如:
- 字符串是
"2023-01-01",但 pattern 写成"yyyy/MM/dd"(用了斜杠)→ 报错 - 字符串含中文空格或全角符号(如“2023-01-01”),pattern 是英文半角 → 不匹配
- pattern 是
"yyyy-MM-dd HH:mm:ss",但字符串只有"2023-01-01"(缺时分秒)→ 报错
建议:把字符串和 pattern 并排打印出来,逐字符比对,尤其注意空格、冒号、短横线、斜杠是否一致;可用 string.trim() 去首尾空格,避免隐藏空白符干扰。
注意大小写和字母含义差异
SimpleDateFormat 对大小写敏感,且不同字母代表不同含义:
立即学习“Java免费学习笔记(深入)”;
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
-
Y(大写)是“周年的年”,y(小写)才是“日历年”——通常用y -
M是月份(1–12),m是分钟;H是24小时制小时,h是12小时制小时 -
S是毫秒(0–999),s是秒;D是一年中的第几天,d是一个月中的第几天
写错一个字母就可能解析失败或结果错误。例如把 dd 写成 DD,输入 "2023-01-05" 就会报错,因为 DD 要求是“一年中第5天”,即 "005" 这样的三位数。
处理带时区或非标准格式的字符串
如果字符串含时区(如 "2023-01-01T12:00:00+0800" 或 "2023-01-01 12:00:00 CST"),默认 SimpleDateFormat 无法识别 ISO 8601 或常见时区缩写:
- 推荐改用
java.time新 API:DateTimeFormatter+ZonedDateTime.parse()或OffsetDateTime.parse() - 若必须用
SimpleDateFormat,需手动设置时区:sdf.setTimeZone(TimeZone.getTimeZone("GMT+8")),且 pattern 中要加z或Z(如"yyyy-MM-dd HH:mm:ss Z"),对应字符串末尾必须是+0800格式 - 遇到
CST这类模糊时区名,JDK 解析不稳定,建议统一转为+0800再解析
避免线程安全问题导致的隐性错误
SimpleDateFormat 不是线程安全的。多线程共用同一个实例时,可能因内部状态被并发修改而抛出 ParseException,且错误难以复现:
- 不要将
SimpleDateFormat声明为 static 公共变量 - 推荐方案:每次解析都新建实例(轻量,性能可接受);或使用
ThreadLocal<simpledateformat></simpledateformat>缓存;或直接迁移到线程安全的DateTimeFormatter - 如果发现“偶尔报错、重启后又正常”,大概率是线程安全问题
不复杂但容易忽略。

















