问题出现
public class dateformate {
public static void main(String[] args) throws Exception {
dateTest();
}
public static void dateTest() throws Exception {
SimpleDateFormat df1 = new SimpleDateFormat("YYYY-MM-dd");
SimpleDateFormat df2 = new SimpleDateFormat("yyyy-MM-dd");
Calendar c = Calendar.getInstance();
c.set(Calendar.YEAR, 2021);
c.set(Calendar.MONTH, 11);//此处是11,但表示的是12月,应为从0开始计算的
// 2021年12月25日周六
c.set(Calendar.DATE, 25);
System.out.println("YYYY-MM-dd = " + df1.format(c.getTime()));
System.out.println("yyyy-MM-dd = " + df2.format(c.getTime()));
// 分割线
System.out.println("========================");
// 2021年12月26日 周日
c.set(Calendar.DATE, 26);
System.out.println("YYYY-MM-dd = " + df1.format(c.getTime()));
System.out.println("yyyy-MM-dd = " + df2.format(c.getTime()));
}
}
看上面代码,猜测结果,四个输出的时间应该是一样的,应该是如下显示:
YYYY-MM-dd = 2021-12-25
yyyy-MM-dd = 2021-12-25
========================
YYYY-MM-dd = 2021-12-26
yyyy-MM-dd = 2021-12-26
Process finished with exit code 0
但实际不然,实际上却是以下的结果:
YYYY-MM-dd = 2021-12-25
yyyy-MM-dd = 2021-12-25
========================
YYYY-MM-dd = 2022-12-26 #这里变成了2022年
yyyy-MM-dd = 2021-12-26
Process finished with exit code 0
分析
为啥会出现以上问题,这就涉及到这两种格式化时间的方式:
YYYY
的格式化规则是 week-based-year
,意思是要通过这周的最后一天属于的年份来确定YYYY
改格式化为哪一年,每一周是以周日开始,周六结束的,以上的2021-12-26
是周日:
周日 | 周一 | 周二 | 周三 | 周四 | 周五 | 周六 |
---|---|---|---|---|---|---|
26 | 27 | 28 | 29 | 30 | 31(跨年) | 1 |
通过以上日历看出:这一周的最后一天是周六
,也就是1
号,但是这是2022
年的1
号,所以就会把这这个日期格式化为2022
年的。
然而yyyy
则是另一种格式化规则:year-of-era
,可以将其理解为以年度计算,并没有其他的特别的规则,当天属于哪一年就会格式化为哪一年。
总结
为了避免这种问题的发生,格式化日期的时候,选择小写的yyyy
即可。
yyyy-MM-dd HH:mm:ss #小 大 小 大 小 小
yyyy/MM/dd HH:mm:ss