生产事故 java_2020 年的第一天,程序员鸭血粉丝又碰上生产事故

3a0af0255db5dc6298e1f47faacc067b.png

本篇文章投稿给 Java 极客技术,欢迎各位小伙伴关注

hello~各位读者新年好,我是鸭血粉丝(大家可以称呼我为「阿粉」),一位喜欢吃鸭血粉丝的程序员!2019 年,阿粉写了很多 bug,这不前一段时间 OOM 差点就把服务器搞挂。跨年的时刻,阿粉默默立下一个 flag,2020 年再见 bug。

732f75cc5cc83d8c95920167a9d9eef4.png

可是没想到还没过几个小时,刚立的 falg 就倒下了,阿粉太难了 😭。。。。

事件回顾

新年第一天,运营反馈商户收到对账文件有问题。刚接到电话时,阿粉是一万个不相信,这个代码都跑了这么久,怎么就偏偏今天不对了。可能看到阿粉不信,运营小姐姐随即发了一张商户给的账单截图。

49ef9ce00a4e25953a1ac4cb19b8d797.png

waht???2020 年才刚来,时间怎么变成 20201231 了。。。

619c713e837954adbc035abdb08aee95.png

哎,阿粉只好先让运营稳住商户,然后赶紧起来,打开了电脑,首先定位一下问题。

问题排查

生成账单伪代码如下:

fc650ed75fd2ebe649c0e8c2f0638ee3.png

上面代码逻辑其实非常简单,将账单数据从数据库取出,然后按照按照相应的格式组装数组,写入文件。

阿粉走查了几遍代码,越看越觉得没问题啊,这么简单的问题没可能出现问题呀。没办法,只好请教一下阿粉的好朋友兼同事小黑。

很快小黑就给阿粉指出 YYYY/MM/dd HH:mm 格式不对,需要使用 yyyy/MM/dd HH:mm 。阿粉修改之后,重新生成对账单,解决这个问题。

原因分析

虽然解决了问题,但是阿粉其实还是一知半解,所幸元旦也没什么事,阿粉就深入研究一下 YYYY 格式。原来 Java 中 YYYY 与 yyyy 分别代表两种不同格式。

0a72bd9829c081c67092a95b6c8dc09c.png

Y 代表 Week Year ,表示当天周所在的年份。这种方式将会把一年划分成 52 周/53 周(类似于闰年的概念,每隔几年将会增加一周)。 Week Year 下每周仅属于某一年,如果某年的第一周或最后一周跨年,就会导致部分日期年份与实际不符。

Week Year 存在两种标准:

ISO 8601:国际标准,每周从周一开始,每年的第一周至少包含 4 天

Common:通用标准,每周从周日开始,每年的第一周至少包含 1 天

Calendar 对象可以通过 setFirstDayOfWeek 与 setMinimalDaysInFirstWeek 改变上面默认标准

Java 将会根据系统环境变量决定使用哪种标准,可以通过设置 Locale 改变方式。代码如下:

// 选择 20191229 这一天

Date date20191229 = DateUtils.parseDate("20191229", "yyyyMMdd");

// 将会输出 2020,使用 Common 。当前系统,Locale 默认值为 Locale.CHINA

System.out.println(DateFormatUtils.format(date20191229,"YYYY"));

// 将会输出 2019,使用 ISO 8601

System.out.println(DateFormatUtils.format(date20191229,"YYYY", Locale.FRANCE));

下面例子我们使用 ISO 8601 标准,分别看一下最后一周跨年以及第一周跨年的例子。

2015 年最后一周跨年,2016 前三天使用 YYYY 最后结果为 2015,时间看起来被回退了。

a1fba38f90ed6246e50b6fe07c2bf119.png

2020 年第一周跨年,2019 年最后两天使用 YYYY 结果为 2020。

d1d8029889b885f0d75f1e8f9946d0c3.png

其他分析

终于弄明白 YYYY ,阿粉顺便也学习一下常用的日期格式。

下面以 2019-12-31 06:06:06:666 时间为例

Letter

含义

Example

Y

Week Year

YYYY---->2020

y

yyyy------>2019

M

MM------->12

m

mm-------->06

D

一年中天数

MM-------->365

d

一月中的天数

dd--------->06

H

小时(0-23)

HH--------->06

h

小时(1-12)

hh---------->06

S

毫秒

SSS--------->666

技术总结

下面开始本篇文章的技术总结:

第一,切记 YYYY 与 yyyy 区别,年份最好统一使用 yyyy

第二,怕忘记的小伙伴可以安装一下阿里的 Alibaba Java Coding Guidelines 插件,这个插件可以检测出使用 YYYY 的代码

第三,阅读完整文档,消除 Bug 最好的的办法就是阅读完整的文档,奥利给

第四,测试环节增加边界测试,早发现,早消灭

随便聊聊

写这篇的文章时候,发现社区有些小伙伴也踩到这个坑,哈哈,吾道不孤也。

2021,2022....阿粉相信还会有新的小伙伴将会踩到这个坑,哈哈。在这里,阿粉给未来小伙伴留个言:

未来的的小伙伴你好,当你搜索到这篇文章并且看到这里,我知道你也踩到坑了,哈哈!既然都看到这里了,别忘记点个赞哦!

ef2f0fbcbd0c9ab456c6f30034d716c6.png

帮助

欢迎关注我的公众号:程序通事,获得日常干货推送。如果您对我的专题内容感兴趣,也可以关注我的博客:studyidea.cn

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值