时间格式 YYYY-MM-dd 的 bug

这篇博客记录了一个项目中遇到的时间格式bug,当使用YYYY-MM-dd而非yyyy-MM-dd时,2019-12-31会被错误地显示为2020-12-31。问题源于'Y'代表的是基于周的年,而'y'代表的是普通的年。文章探讨了这两个符号的区别以及可能导致使用YYYY的情景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前一阵子,我们项目中遇到了一个 bug,时间格式的bug,2019-12-31那天显示成了2020-12-31,在网上一搜,也有其他人遇到了同样的 bug,这里就对这个问题记录一下。

一直以来使用 yyyy 和 YYYY 结果都一样,也就没有去研究它们之间的区别,但是这次遇到了这个 bug,所以就去研究了一下。那么产生这个 bug 的原因是什么呢?其实很简单,就是把 yyyy-MM-dd 写成了 YYYY-MM-dd 。

一、当时间是 2019-08-31 时,代码如下:

public class DateTest {
  public static void main(String[] args) {
    Calendar calendar = Calendar.getInstance();
    
    calendar.set(2019, Calendar.AUGUST, 31);
    
    Date strDate = calendar.getTime();
    
    DateFormat formatUpperCase = new SimpleDateFormat("yyyy-MM-dd");
    System.out.println("2019-08-31 to yyyy-MM-dd: " + formatUpperCase.format(strDate));
    
    formatUpperCase = new SimpleDateFormat("YYYY-MM-dd");
    System.out.println("2019-08-31 to YYYY/MM/dd: " + formatUpperCase.format(strDate));
  }
}

结果为:

2019-08-31 to yyyy-MM-dd: 2019-08-31
2019-08-31 to YYYY/MM/dd: 2019-08-31

这里是没有问题的, 使用 yyyy-MM-dd 和 YYYY-MM-dd 结果是一样的。

 

二、当时间是 2019-12-31 时,代码如下: 

public class DateTest {
  public static void main(String[] args) {
    Calendar calendar = Calendar.getInstance();

    calendar.set(2019, Calendar.DECEMBER, 31);

    Date strDate = calendar.getTime();

    DateFormat formatUpperCase = new SimpleDateFormat("yyyy-MM-dd");
    System.out.println("2019-12-31 to yyyy-MM-dd: " + formatUpperCase.format(strDate));

    formatUpperCase = new SimpleDateFormat("YYYY-MM-dd");
    System.out.println("2019-12-31 to YYYY/MM/dd: " + formatUpperCase.format(strDate));
  }
}

结果为:

2019-12-31 to yyyy-MM-dd: 2019-12-31
2019-12-31 to YYYY/MM/dd: 2020-12-31

这里出现了问题, 使用 yyyy-MM-dd 时结果为 2019-12-31 是正确的,但是使用  YYYY-MM-dd  结果为 2020-12-31 ,这显然是不对的。

出现这个结果的原因其实很简单,就是因为 Y  和  y  实际上代表了不同的含义,具体含义见下图。

  • y:year-of-era;是正常的年;

  • Y:week-based-year;只要本周跨年,那么这周就算入下一年;

到这里算是明白了这个 bug 的始末,但是想了半天也没有想明白这个 YYYY 它的意义在哪里以及什么样的场景会使用 YYYY 来做时间格式化。这个该不会是 Java 自己的 bug 吧?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值