加菲猫欢乐跑
65.99M · 2026-03-26
近期跨年的时候遇到了这样的时间格式化问题:
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()));
这导致了什么问题?
问题点在哪里?
ISO-8601 标准:
这就导致一个现象:有些 1 月初的日期,可能仍属于“上一年的最后一周”。
比如2025年12月的29、30、31日这三天,如果是Week-Based-Year,那么则归属是2026年,而不是2025年!
观察日历, 得出一个简单的结论: 新的一年所在的那一周,含有上一年的日期, 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-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,没问题
}
本文结束。