问题出现

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