MySQL使用datetime存储日末23:59:59秒出现的Bug

我们的需求是定时在凌晨跑,然后把记录产生的时间置为前一天的最后时间:
比如2022-05-21 00:00:00执行的,存储为2022-05-20 23:59:59
java代码使用的Calendar进行的偏移

Calendar preDate = Calendar.getInstance();
preDate.add(Calendar.DATE,-1);
preDate.set(Calendar.HOUR,23);
preDate.set(Calendar.MINUTE,59);
preDate.set(Calendar.SECOND,59);

然后数据库对应的字段为datetime类型,起初数据库总是偶尔会产生
2022-05-21 00:00:00的数据

示例.png

经过阅读https://www.jianshu.com/p/e5084b43d07c该大神的文章,恍然大悟,
原来是数据库的datetime的毫秒进位导致的,因为我们在使用Calendar的时候并没有设置毫秒位,所以毫秒是跟随当前时间的。

因为MySQL毫秒部分需要以参数形式传参给数据类型,默认是不保存毫秒的,可以保存1-6位。如果需要保存三位的毫秒值,数据类型可以定义为DATETIME(3)TIMESTAMP(3),不需要保存毫秒的话,只需要将类型直接写为DATETIMETIMESTAMP

这样的话假如代码执行Calendar的时候如果毫秒位>=500,则在存储进MySQL的时候会发生进位,这就是Bug产生的原因。
解决办法:
1> 改代码,设置毫秒位为0或者小于500就行

Calendar preDate = Calendar.getInstance();
preDate.add(Calendar.DATE,-1);
preDate.set(Calendar.HOUR,23);
preDate.set(Calendar.MINUTE,59);
preDate.set(Calendar.SECOND,59);
preDate.set(Calendar.MILLISECOND, 0);

2> 把数据库字段改为datetime(3)或者把数据库字段改为varchar存储

你可能感兴趣的:(MySQL使用datetime存储日末23:59:59秒出现的Bug)