当前位置: 首页 > news >正文

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

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

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年!

image

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

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

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

怎么解决?

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

@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-30System.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。

本文结束。

http://www.jsqmd.com/news/412537/

相关文章:

  • 《P1973 [NOI2011] NOI 嘉年华》
  • 华为OD机考双机位C卷 - 几何平均值最大子数组 (Java Python JS GO C++ C)
  • 实现一个简单的文本摘要生成器。
  • pyTorch环境搭建及遇到的算力问题
  • 卷积神经网络(CNN)简介-卷积神经网络介绍
  • 【RCCL】RCCL工具
  • 大数据交易数据湖架构设计指南
  • 2026年2月25日
  • 什么是动态住宅 IP 代理?动态 IP 最常用在哪些业务
  • 搜索已死,问答永生:2026年6大特色GEO服务商实战图谱与避坑指南 - 品牌2025
  • LLM支持的AI Agent上下文感知推荐技术
  • langchain架构设计以及应用案例分享
  • AI获客新范式:2026年6大优质GEO服务商全景解析与实战指南 - 品牌2025
  • TypeScript学习
  • 工业AI的赛道有哪些主要玩家?全球竞争格局与未来趋势探讨
  • pycharm安装及环境配置
  • 整车制造计划排程排产系统的创新与实践
  • 工业超级智能体在整车制造如何实现生产优化与决策协同?
  • 告别盲目投放:2026年七大GEO服务商深度拆解与精准匹配 - 品牌2025
  • Rust学习笔记第2篇
  • 2026年负债人必看:如何合法高效解决信用卡债务问题? - 代码非世界
  • 网贷协商最佳解决方案,教你找到靠谱的债务协商服务商 - 代码非世界
  • 2026年贷款债务协商全攻略,2026年信用卡贷款债务协商,正确的解决方案到底是什么? - 代码非世界
  • 2026年信用卡/贷款逾期后,如何合法协商分期还款? - 代码非世界
  • 《白色相簿2》《歌を忘れた偶像》终章-雪菜线玩后感
  • docker 入门
  • docker 入门2
  • 深入解析 MobileNetV2:边缘AI场景中最常用的轻量化卷积神经网络
  • Perl 条件语句详解
  • docker 镜像备份