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