YYYY-MM-DD 的黑锅,我们不背!

简介: 写这篇博文是记录下跨年的bug。

写这篇博文是记录下跨年的bug。


去年隔壁组的小伙伴就是计算两个日期之间间隔的天数,因为跨年的原因计算有误。


当时测试组的小姐姐也没有模拟出来这种场景,导致上生产环境直接影响线上的数据。


今天逛技术论论坛正好遇到Java日期的操作bug。


1 yyyy 和 YYYY

别看字,看代码

@Test
public void testWeekBasedYear() {
  Calendar calendar = Calendar.getInstance();
  // 2019-12-31
  calendar.set(2019, Calendar.DECEMBER, 31);
  Date strDate1 = calendar.getTime();
  // 2020-01-01
  calendar.set(2020, Calendar.JANUARY, 1);
  Date strDate2 = calendar.getTime();
  // 大写 YYYY
  SimpleDateFormat formatYYYY = new SimpleDateFormat("YYYY/MM/dd");
  System.out.println("2019-12-31 转 YYYY/MM/dd 格式: " + formatYYYY.format(strDate1));
  System.out.println("2020-01-01 转 YYYY/MM/dd 格式: " + formatYYYY.format(strDate2));
  // 小写 YYYY
  SimpleDateFormat formatyyyy = new SimpleDateFormat("yyyy/MM/dd");
  System.out.println("2019-12-31 转 yyyy/MM/dd 格式: " + formatyyyy.format(strDate1));
  System.out.println("2020-01-01 转 yyyy/MM/dd 格式: " + formatyyyy.format(strDate2));
}

输出结果:

2019-12-31 转 YYYY/MM/dd 格式: 2020/12/31
2020-01-01 转 YYYY/MM/dd 格式: 2020/01/01
2019-12-31 转 yyyy/MM/dd 格式: 2019/12/31
2020-01-01 转 yyyy/MM/dd 格式: 2020/01/01

细心的同学应该发现了2019-12-31用YYYY/MM/dd 此刻变成了2020/12/31


??为何呢?


YYYY这么大的能耐,能跑到2020年代去?


我2019年底买的东西,你如果用YYYY来格式化出库日期,我是不是得到2020年底才能收到货?此bug问题挺大的呀!


YYYY 到底是何方妖怪?**👺**

Java's DateTimeFormatter pattern "YYYY" gives you the week-based-year, (by default, ISO-8601 standard) the year of the Thursday of that week.


例子:

下面就是用YYYY格式化代码


12/29/2019 将会格式化到2019年 这一周还属于2019年


12/30/2019 将会格式化到2020年 这一周已经属于2020年


看字说话YYYY,week-based year 是 ISO 8601 规定的。


2019-12-31号这一天,安周算年份已经属于2020年了,格式化之后就变成2020年,后面的月份日期不变。


2 dd 和 DD

private static void tryit(int Y, int M, int D, String pat) {
  DateTimeFormatter fmt = DateTimeFormatter.ofPattern(pat);
  LocalDate dat = LocalDate.of(Y,M,D);
  String str = fmt.format(dat);
  System.out.printf("Y=%04d M=%02d D=%02d " +
    "formatted with " +
    "\"%s\" -> %s\n",Y,M,D,pat,str);
}
public static void main(String[] args){
  tryit(2020,01,20,"MM/DD/YYYY");
  tryit(2020,01,21,"DD/MM/YYYY");
  tryit(2020,01,22,"YYYY-MM-DD");
  tryit(2020,03,17,"MM/DD/YYYY");
  tryit(2020,03,18,"DD/MM/YYYY");
  tryit(2020,03,19,"YYYY-MM-DD");
}

输出结果:

Y=2020 M=01 D=20 formatted with "MM/DD/YYYY" -> 01/20/2020
Y=2020 M=01 D=21 formatted with "DD/MM/YYYY" -> 21/01/2020
Y=2020 M=01 D=22 formatted with "YYYY-MM-DD" -> 2020-01-22
Y=2020 M=03 D=17 formatted with "MM/DD/YYYY" -> 03/77/2020
Y=2020 M=03 D=18 formatted with "DD/MM/YYYY" -> 78/03/2020
Y=2020 M=03 D=19 formatted with "YYYY-MM-DD" -> 2020-03-79

看到没有?

最后的3个日期都错误了,这里的大写的DD代表的是处于这一年中那一天,不是处于这个月的那一天。

小伙伴们一定要记住了不要犯类似的错误。

3、结论

YYYY和yyyy不一样的,DD和dd也是不一样要切记。

此锅我们不背。

相关文章
|
SQL 运维 API
Apache Flink 学习教程----持续更新
Apache Flink 学习教程----持续更新
548 0
|
安全 应用服务中间件 文件存储
Kerberos网络身份认证协议介绍及SMB文件系统对其的支持
本文简单介绍了Kerberos网络认证协议,以及SMB文件系统对Kerberos认证的支持。
7761 1
Kerberos网络身份认证协议介绍及SMB文件系统对其的支持
|
资源调度 负载均衡 Kubernetes
【Flink on Yarn的三种部署方式详细介绍,及应用场景】
Flink on Yarn的三种部署方式,Session模式,Per-Job模式,application模式,他们为何会诞生,我们要用哪种模式来部署
1774 1
【Flink on Yarn的三种部署方式详细介绍,及应用场景】
|
Unix Linux Apache
离线安装Superset 0.37(截图详细版)
上文提到了Superset 0.37的在线安装方式,只需要更新pip,然后pip install就可以了。但是在生产环境中,特别是内网环境中,很多时候是没有外网的,这时候就需要采取离线安装的方式。 本文将详细介绍在Linux系统中离线安装Superset的全过程,并整理了安装过程中遇到的错误。
1375 0
离线安装Superset 0.37(截图详细版)
|
SQL 分布式计算 监控
大数据最后一公里——2021年五大开源数据可视化BI方案对比
大数据在经过前几年的野蛮生长以后,开始与数据中台的概念一同向着更实际的方向落地。有人问,数据可视化是不是等同于数据大屏。数据大屏是数据可视化的一部分,其承载更多的是展示与监控的功能。 而真正对业务产生影响的,确是比较低调的自助数据可视化系统(商用的一般称之为BI系统),支撑着公司的指标体系,为业务的发展,企业的数字化驱动提供帮助。
2136 0
大数据最后一公里——2021年五大开源数据可视化BI方案对比
|
Python
pip安装包报错Could not find a version that satisfies the requirement pymysql (from versions: none)
pip安装包报错Could not find a version that satisfies the requirement pymysql (from versions: none)
1317 1
|
消息中间件 Java 中间件
链路跟踪-SkyWalking系列(三)
链路跟踪-SkyWalking系列(三)
|
Python
从bag包中提取图片和点云数据为pcd格式点云文件
从bag包中提取图片和点云数据为pcd格式点云文件
1018 0
|
SQL 存储 Java
一文帮你搞定MyBatis的类型转换模块,深度好文,欢迎一键三连!!!
MyBatis是一个持久层框架ORM框架,实现数据库中数据和Java对象中的属性的双向映射,那么不可避免的就会碰到类型转换的问题,在PreparedStatement为SQL语句绑定参数时,需要从Java类型转换为JDBC类型,而从结果集中获取数据时,则需要从JDBC类型转换为Java类型,所以我们来看下在MyBatis中是如何实现类型的转换的。
一文帮你搞定MyBatis的类型转换模块,深度好文,欢迎一键三连!!!