Java中YYYY-MM-dd在跨年时出现的bug

先看一张图:

Bug的产生原因:

日期格式化时候,把 yyyy-MM-dd 写成了 YYYY-MM-dd 

Bug分析:

当时间是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

当时间是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 ,这显然是不对的。

日期格式化时,yyyy表示当天所在的年,而大写的YYYY代表的是week in which year(JDK7之后引入的概念)意思是当天所在的周属于的年份,案例中的2019-12-31这一天,本周跨年,按周算年份已经属于2020年,所以返回的YYYY就是2020年。

参考Class DateTimeFormatter的官方文档:

https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html#patterns

 

 

参考javadoc中对week-based-year的说明:

https://docs.oracle.com/javase/8/docs/api/java/time/temporal/WeekFields.html

 

posted @ 2022-11-27 01:49  ycyzharry  阅读(355)  评论(0编辑  收藏  举报