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

SimpleDateFormat.parse()使用"YYYY/MMM/d"返回错误日期求助

问题根源:混淆了YYYY和yyyy的区别

哈哈,这个坑我之前也踩过!你遇到的错误日期问题,核心原因就是误用了周年份格式符YYYY,而不是我们日常用的日历年份格式符yyyy。

先搞清楚两者的差异:

  • yyyy:这是我们熟悉的常规日历年份,对应格里高利历里的年份,就是平时说的“2019年”这种。
  • YYYY:这个是周年份,指的是当前日期所在的周所属的年份。周年份的规则有点特殊:它的第一周是包含该年第一个“周起始日”(比如很多地区是周一,部分是周日,取决于Locale)的那一周,或者按ISO标准是包含1月4日的那一周。这就导致,年初或年末的某些日期,周年份可能和日历年份不一样(比如2019年1月1日,在ISO周规则里属于2018年的第52周)。

结合你的代码分析:

你格式化2019年4月9日时用YYYY,得到2019/Apr/9是没问题的——这一天的周年份确实是2019。但解析环节出问题了:
当你用YYYY去解析2019/Apr/9时,解析器会把2019当作周年份,但你同时提供了月份(Apr)和日期(9),这两个属于日历日期体系,和周年份体系不兼容。SimpleDateFormat在这种冲突场景下,会默认取周年份2019的第一周,然后尝试匹配你给的月日,结果就出现了日期回退到2018年12月31日的错误——因为在AST时区,2019年的第一周起始日期就是2018年12月31日。

解决方案:把YYYY改成yyyy

只需要修改格式字符串,用yyyy替代YYYY,就能让格式化和解析都正常工作:

Date date = new Date();
System.out.println(date);
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy/MMM/d");
String dateString = simpleDateFormat.format(date);
System.out.println(dateString);
date = simpleDateFormat.parse(dateString);
System.out.println(date);

运行这段代码,解析后的日期就会和原日期一致,不会再出现跳转到2018年的问题。

额外建议:优先使用Java 8+的新日期API

如果你的项目是Java 8及以上版本,强烈建议用java.time包下的类(比如DateTimeFormatter、LocalDate)替代SimpleDateFormat。新API设计更清晰,完全避免了这类格式符混淆的问题,而且是线程安全的,示例代码如下:

LocalDate date = LocalDate.now();
System.out.println(date);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MMM/d");
String dateString = date.format(formatter);
System.out.println(dateString);
date = LocalDate.parse(dateString, formatter);
System.out.println(date);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 05:03:27