8

YYYY-MM-DD 的黑锅,服务端去背!

 4 years ago
source link: http://mp.weixin.qq.com/s?__biz=MzIxNzU1Nzk3OQ%3D%3D&%3Bmid=2247489951&%3Bidx=2&%3Bsn=0e2458fa264cc526e5fd3bc22971d7bb
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

code小生  一个专注大前端领域的技术平台

公众号回复 Android 加入安卓技术群

RNz6zyA.jpg!web

作者:兔子托尼啊

https://zhuanlan.zhihu.com/p/101150248

写这篇博文是记录下跨年的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-31YYYY/MM/dd 此刻变成了 2020/12/31

??为何呢?

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

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

YYYY 到底是何方妖怪? :japanese_goblin:

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也是不一样要切记。

此锅我们不背。

推荐阅读

三年 Android 经验面经

7 个开源的 Spring Boot 前后端分离项目,一定要收藏!

试试 IntelliJ IDEA 自带的高能神器!

Android Jetpack 最佳开发姿势

2019年终总结,一位本命年程序猿的年终总结

B3Q7faa.jpg!web

如果你有写博客的好习惯

欢迎投稿

点在看,小生感恩大家 :heart:


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK