0%

Java YYYY-MM-dd 问题

因为 YYYY-MM-dd 被叫去加班了…

今天看到群里小伙伴吐槽一早被叫起来修Bug,定睛一看,要修的BUG居然是YYYY-MM-dd问题
如果你正好碰到的,可以看看了解下原因,做好相应的处理;如果还没碰到的,最好也自查一下。

事故现场

我们先来写个单元测试,重现一下这个问题。

测试逻辑:

  1. 创建两个日期格式化:
    一个是存在问题的YYYY-MM-dd
    另一个是正确用法yyyy-MM-dd
  2. 分别去格式化两个不同的日期:2021年12月25日(周六),2020年12月26日(周日)
    具体代码如下:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    public class Tests { 

    @Test
    public void test() 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);

    // 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()));
    }

    }
    跑一下测试,可以看到输出结果如下:
    1
    2
    3
    4
    5
    YYYY-MM-dd = 2021-12-25
    yyyy-MM-dd = 2021-12-25
    ========================
    YYYY-MM-dd = 2022-12-26
    yyyy-MM-dd = 2021-12-26
  • 2021年12月25日(周六),两种格式化都正确
  • 2021年12月26日(周日),YYYY-MM-dd出了问题,年份到了2022年
问题原因

什么YYYY-MM-dd格式化2021年12月26日的时候,会到2022年呢?

因为YYYY是week-based-year,表示:当天所在的周属于的年份,一周从周日开始,周六结束,只要本周跨年,那么这周就算入下一年。

所以2021年12月26日那天在这种表述方式下就已经到 2022年了。

而当使用yyyy的时候,就还是 2021 年。