SimpleDateFormat(“YYYY-MM-dd“)格式化时间出现了bug?

近期跨年的时候遇到了这样的时间格式化问题:

java 复制代码
Calendar ca = Calendar.getInstance();
ca.set(Calendar.YEAR, 2025);
ca.set(Calendar.MONTH, Calendar.DECEMBER);
ca.set(Calendar.DAY_OF_MONTH, 25);

SimpleDateFormat sdf = new SimpleDateFormat("YYYY-MM-dd");
//输出:2025-12-25,没问题
System.out.println(sdf.format(ca.getTime()));

ca.set(Calendar.DAY_OF_MONTH, 30);
//输出:2026-12-30,有问题,我的预期是输出:2025-12-30
System.out.println(sdf.format(ca.getTime()));

这导致了什么问题?

  • 我们系统的某个业务功能要按照年月日来生成文件夹和命名文件,由于使用了这种时间的格式化,导致了系统奇怪地出现了26年12月的文件夹,明明是在2025年啊;有些文件也被命名为了"20261231xxxx"。
  • 年末3天的缓存数据,放入是成功的,但是获取就是获取不到,key奇怪地出现了20261231,明明期望的应该是20251231。
  • 热点讨论功能前端要展示时间:刚刚、5分钟前、昨天 14:30、3天前、一年前。2025年12月29日这天的数据,前端居然永远展示"刚刚"。

问题点在哪里?

  • 格式化年份的占位符使用了YYYY。
  • 在SimpleDateFormat中,YYYY 是基于周(Week-Based-Year)的年份,而不是基于日期所在年的年份。

++什么是 Week-Based-Year?++

ISO-8601 标准:

  • 一周从星期一开始
  • 一年中的第一周,必须包含至少 4 天的新年

这就导致一个现象:有些 1 月初的日期,可能仍属于"上一年的最后一周"。

比如2025年12月的29、30、31日这三天,如果是Week-Based-Year,那么则归属是2026年,而不是2025年!

观察日历, 得出一个简单的结论: 新的一年所在的那一周,含有上一年的日期, YYYY方式 格式化 都会格式化错误。

**什么时候才应该使用 YYYY?**只有在做"基于周的统计"时才使用:

  • 周报系统
  • 财务周统计
  • 周序号计算

++怎么解决?++

**所以解决方案是:**时间格式化时用yyyy-MM-dd✅,而不是YYYY-MM-dd❌。

java 复制代码
@Test
public void test() {
    Calendar ca = Calendar.getInstance();
    ca.set(Calendar.YEAR, 2025);
    ca.set(Calendar.MONTH, Calendar.DECEMBER);
    ca.set(Calendar.DAY_OF_MONTH, 25);

    SimpleDateFormat sdf_wrong = new SimpleDateFormat("YYYY-MM-dd");
    SimpleDateFormat sdf_right = new SimpleDateFormat("yyyy-MM-dd");

    //输出:2025-12-25,没问题
    System.out.println(sdf_wrong.format(ca.getTime()));
    System.out.println(sdf_right.format(ca.getTime()));

    ca.set(Calendar.DAY_OF_MONTH, 30);
    System.out.println(sdf_wrong.format(ca.getTime())); //输出:2026-12-30,有问题,我的预期是输出:2025-12-30
    System.out.println(sdf_right.format(ca.getTime()));//输出:2025-12-30,没问题

    String format1 = DateTimeFormatter.ofPattern("YYYY-MM-dd").format(LocalDate.of(2025, 12, 31));
    System.out.println(format1);//输出:2025-12-31,没问题
    String format2 = DateTimeFormatter.ofPattern("yyyy-MM-dd").format(LocalDate.of(2025, 12, 31));
    System.out.println(format2);//输出:2025-12-31,没问题
}

++结论++

  • 时间格式化年份时一定要用yyyy,而不是其他。
  • 建议立刻全局搜索YYYY替换为yyyy,除非你非常明确是基于周的年份。
  • 建议使用DateTimeFormatter,而不是SimpleDateFormat。

本文结束。

相关推荐
QQ骞1 天前
【bug的管理流程深入浅出】
软件测试·bug
Rambo.xia1 天前
AXI跨时钟域与数据一致性——CDC FIFO深度不够、写后读冒险、多Master仲裁、乱序返回,出了Bug根本查不出来
fpga开发·bug
不知名的老吴2 天前
思考:要做到Bug Free需培养怎样的思维?
bug
河南花仙子科技4 天前
小游戏开发中常见的BUG类型及成因
人工智能·科技·游戏·bug
c238565 天前
Bug 猎手入门指南
c++·算法·bug
李永奉7 天前
杰理可视化SDK开发-【BUG】配置“TWS两边同时按消息使能”功能后,按键单击功能无效失灵
开发语言·单片机·嵌入式硬件·物联网·bug
AI大模型-小雄7 天前
充值Codex + GPT-5.5 并发 Bug 调试实战:从时序分析到回归测试
gpt·log4j·bug
穷人小水滴8 天前
(科幻) 备用肉身虫 (Backup Body Bug, BBB) 系列设定 (202607 更新)
aigc·bug·科幻
不爱记笔记10 天前
GPT-5.6 Sol 真实项目实测!Bug修复、UI重构与帆船游戏复刻
人工智能·gpt·ui·chatgpt·bug·openai
蒙塔基的钢蛋儿11 天前
记一次 STM32H723 硬件 Bug 排查:写个 ETH 寄存器,SDRAM 数据飞了
stm32·嵌入式硬件·bug