You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SimpleDateFormat日期解析异常:四月被解析为一月的技术问询

为什么SimpleDateFormat解析"Apr 27, 2018, Fri"会得到Jan 05, 2018?

这个问题的核心坑点就是你用了YYYY而不是yyyy来表示年份——这俩格式符看起来像双胞胎,但含义差远了!

先搞懂YYYY和yyyy的本质区别

  • yyyy是我们日常认知里的日历年,也就是从1月1日到12月31日的公历年,完全符合我们对“年份”的常规理解。
  • YYYY是周年份(Week-Based Year),它基于ISO周历规则:一年的第一周是包含该年至少4天的那一周(或者说包含1月4日的那一周),周年份的起止是围绕周来划分的,和日历年的起止不一定重合。比如Locale.US下一周从周日开始,2018年的第一周是2017年12月31日到2018年1月6日,1月5日就是这一周的周五。

为什么解析会出现离谱的结果?

当你在格式字符串里同时混用MMM dd(月份+日历年日期)和YYYY(周年份)时,SimpleDateFormat的解析逻辑直接混乱了:它会把"2018"当成周年份,然后试图匹配"Apr 27"和"Fri",但周年份的日期体系和日历年的月份日期根本不兼容,最后就错误地定位到了周年份2018里的第一个周五——也就是2018年1月5日。

快速解决办法

把格式字符串里的YYYY换成yyyy就行,用日历年的格式符才符合你这个日期字符串的逻辑:

SimpleDateFormat sdf = new SimpleDateFormat("MMM dd, yyyy, EEE", Locale.US);
System.out.println(sdf.format(new Date()));
System.out.println(sdf.format(sdf.parse("Apr 27, 2018, Fri")));

运行后输出就完全符合预期了:

Apr 27, 2018, Fri
Apr 27, 2018, Fri

额外建议(避坑指南)

如果你用的是Java 8及以上版本,真心建议放弃SimpleDateFormat,改用java.time包下的新日期API(比如DateTimeFormatter、LocalDate)。它不仅天生线程安全,还把这些容易混淆的概念划分得更清晰,从根源上避免踩这类坑:

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MMM dd, yyyy, EEE", Locale.US);
LocalDate date = LocalDate.parse("Apr 27, 2018, Fri", formatter);
System.out.println(formatter.format(date)); // 输出 Apr 27, 2018, Fri

内容的提问来源于stack exchange,提问作者user9709261

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 09:02:21