前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >了解一个跨年才出现的bug

了解一个跨年才出现的bug

作者头像
bisal
发布2022-01-04 10:25:21
7950
发布2022-01-04 10:25:21
举报

今天是跨年的临界点,就像闰月一样,应用程序存在出现错误的可能,快看下你的系统,是否存在相同的问题?

这个问题出自之前维护的某套系统,其实当时很多应用都受到了影响,直接从逻辑层面让系统不可用了,只能靠紧急上线解决。一方面说明了我们对某些技术细节并不了解,另一方面则说明测试缺少一些极端边界性的验证。

P. S. 《Java日期中“y”和“Y”的区别

问题需求其实很简单,Java中将一个DATE类型的日期,转换为字符串,其中用到了格式化的方法。但得到的结果,却大相径庭。

出现问题是有特殊的场景,例如,现在是2018年12月30日,执行如下的代码,返回的结果,竟然是30DEC19,不是需要的30DEC18,

db9f0da816bbd0d2bf33be4bd23877b5.png
db9f0da816bbd0d2bf33be4bd23877b5.png

尝试将Locale.US,转换为Locale.UK,此时能正常返回30DEC18,难道是这个导致?

0c9dfd57d87f890809368f05396131d6.png
0c9dfd57d87f890809368f05396131d6.png

参考官方文档,

https://www.oracle.com/technetwork/cn/java/javase/documentation/api-jsp-136079-zhs.html

jdk6的SimpleDateFormat只有"y",没有"Y",

32f880574fc5fe7912fab206578e94b6.png
32f880574fc5fe7912fab206578e94b6.png

P. S. 《JDK的版本号解惑

jdk7和8,甚至jdk9,除了“y”,另外引入了"Y",“Y”表示Week year,

0ec68cb45d938cc85c34839f3d27c3f6.png
0ec68cb45d938cc85c34839f3d27c3f6.png

P.S. https://docs.oracle.com/javase/9/docs/api/java/text/SimpleDateFormat.html

对于“y”和“Y”的关系,如果指定了“Y”,但是不支持week year,那么"y"会替换"Y",可以使用getCalendar().isWeekDateSupported()了解当前版本的jdk,是否支持week year,

If week year 'Y' is specified and the calendar doesn't support any week years, the calendar year ('y') is used instead. The support of week years can be tested with a call to getCalendar().isWeekDateSupported().

Week year的意思是,当天所在的周属于的年份,一周从周日开始,周六结束,只要本周跨年,那么这周就算入下一年。

例如2018年12月30日,如果使用week year,本周跨年(本周日:12月30日-下周六:1月5日),这一周就算入下一年,即12月30日的week year是2019,如果使用“y",则是正常理解的2018,

3e323871f73472caf43850f129b9257a.png
3e323871f73472caf43850f129b9257a.png

此时,仍旧使用“Locale.US”,但是"YY"改为"yy",返回的就是我们需要的30DEC18了,

57508c2348fc5478b3ad54684ffe8d27.png
57508c2348fc5478b3ad54684ffe8d27.png

为了对称比较,“Locale.UK”使用“yy”,显示正常,同样是30DEC18,

f10351528b0cff7603ce41d363c62d01.png
f10351528b0cff7603ce41d363c62d01.png

其实Calendar类提供了非常多的方法,例如若想知道,当天在一年中的周数,可以使用如下code,针对2018年12月30日,他会返回1,

15831d5bccf4fa203eb66d9eddb7d3ed.png
15831d5bccf4fa203eb66d9eddb7d3ed.png

从上面的介绍,可以知道,一个小小的“y”和“Y”,就有不同的含义,要是不了解,就可能产生错误,而且不是特殊的场景,这种问题很难测出来,容易造成隐患。

要么了解这两者的区别,和适用的jdk版本,要么大多数场景,就用“y”,基本都能满足实际要求,就不要用“Y”了。

但是,就像在这次数据技术嘉年华大会上,分享中提到的,对待知识,需要“知其然”,更要“知其所以然”,日积月累,才可能逐步做到能力的提升,否则只是解决一个问题,不做任何思考,他的作用可能就只局限于“这个问题”,

4e3cc2d306a359802e67a70388fb9361.png
4e3cc2d306a359802e67a70388fb9361.png
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2021-12-31 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档