一只爱阅读的程序员

一只爱阅读的程序员

一、问题由来

前一天下午正在写代码的时候,领导突然走过来跟我说,让我去看一个神秘的BUG,说是在数据库中查询时的一个日期

返回到页面后,查询时间倒退了一天。一听到这个BUG,我就感觉很奇怪,还有这样的BUG?也让我满是期待,究竟是

什么样的BUG会导致这个问题呢?


二、问题分析

 这就是一个很简单的列表查询,查询条件都只有一个怎么出现这么奇怪的BUG呢?我立马在本地测试了一下,结果还真是时间向前

倒退了一天。这个是查询的结果,

查询时间倒退一天-项目中惊现神秘BUG-JsonFormat使用采坑记-LMLPHP

这个是使用Swagger测试的结果,

查询时间倒退一天-项目中惊现神秘BUG-JsonFormat使用采坑记-LMLPHP

 以0002这家企业为例,数据库查询的tableDate为2020-09-01,可是返回到页面中时却是2020-08-31,日期确实向前减了一天。

看到这个测试结果让我很惊讶,还真神了。这是时间发生错乱了嘛,还是发生时空穿梭了,问题竟然还真出现了。我去看了另外

一个查询,只查询年份的一个接口,结果更神奇,年份的查询结果为1970年。数据库查询结果如下,

查询时间倒退一天-项目中惊现神秘BUG-JsonFormat使用采坑记-LMLPHP

 页面中返回的结果为,

查询时间倒退一天-项目中惊现神秘BUG-JsonFormat使用采坑记-LMLPHP

 自己看到这结果都不得不相信这个现实。接着开始排查原因,查询年份的数据在返回页面前打印的数据为,

查询时间倒退一天-项目中惊现神秘BUG-JsonFormat使用采坑记-LMLPHP

 从打印的结果来看是正确的,没什么异常。可是查看第一个查询最后返回的数据时,发现有不对劲的地方,最后返回的是时间戳,而不是字符串的日期。

查询时间倒退一天-项目中惊现神秘BUG-JsonFormat使用采坑记-LMLPHP

 我将时间戳转换为日期后发现也是正确的,

查询时间倒退一天-项目中惊现神秘BUG-JsonFormat使用采坑记-LMLPHP

 接着进一步排查,看看这两个输出类中对应的日期字段是什么,

查询时间倒退一天-项目中惊现神秘BUG-JsonFormat使用采坑记-LMLPHP

 查询时间倒退一天-项目中惊现神秘BUG-JsonFormat使用采坑记-LMLPHP

 这两个返回的输出类中,日期字段都使用了java中的Date类型,并且使用了一个注解JsonFormat注解。这个注解是同事推介使用的,

使用这个注解的好处是,不需要在查询的SQL中对查询结果有日期、时间的字段做格式化处理,格式化日期和时间的操作全部放在Java

的输出类中来进行处理。这样对于我们开发来说,改动的代码量会小很多,不然不同的数据库比如Mysql和Oracle就需要使用不同的语法

进行格式化。对于开发来说,有复杂和简单的两种方法来解决问题,如果有得选,那么我一定会选择简单的办法来处理问题。

自己尝试使用各种办法,比如格式化日期时使用年月日时分秒,没有解决;输出类中使用字符串来接收查询的日期类型,可以解决。

到此可以确定一点就是格式化这里出问题了。


三、解决方案

和同事说了这个问题后,同事帮忙查询原因,最终找到一篇文章,找到了这个问题的解决办法。https://blog.csdn.net/a992795427/article/details/87094200

问题的原因是在使用JsonFormat这个注解时,使用的时区不一样,默认使用的是标准的格林威治时间,而我们中国所在的时区为东八区,需要在默认

时区上面加8个小时,记得这好像是初中的地理常识。在配置文件中添加上这一行配置之后,

spring.jackson.time-zone=GMT+8

问题解决。另外一个问题,只查询年份的时候,年份变为1970年的原因是使用JsonFormat注解格式化日期时,不能直接格式化为年份。这是通过实践

得出的经验。至此神秘BUG终于解决。

12-09 21:46