Java中Date存储到MySQl字段时间不一致问题

问题情景

在 Java 代码中使用 new Date() 赋值日期,存储到数据库 DATETIME 字段后,在数据库中多了一秒,经过排查是数据库对Java Date 值进行了四舍五入,导致此问题。

问题剖析

Java 的 java.util.Date 类时间精确度到毫秒(milliseconds),MySQl 中的日期时间类 TIMEDATETIMETIMESTAMP 最大可以支持 6 位,即精确到毫秒(microseconds),以格式 type_name(fsp) 格式进行定义,如 DATETIME(3) 为定义精确到秒后 3 位(毫秒)。当不指定 fsp 的时候,默认值为 0,即最大精确度保留到秒。

此问题场景下,MySQL 的 DATETIME 未指定精确度,最大精确度为秒,而 java.util.Date 精确度为毫秒,MySQl会对末尾的时间进行四舍五入,当毫秒值大于 500 时,便会进 1 位增加一秒,造成了此问题。

从 MySQl 8 开始,可以通过启用 TIME_TRUNCATE_FRACTIONAL 参数使用截断模式,即直接移除末尾小数,不进行四舍五入。

测试代码

DROP TABLE IF EXISTS fractest;  
CREATE TABLE fractest( c1 TIME(2), c2 DATETIME(2), c3 TIMESTAMP(2) ); 

INSERT INTO fractest VALUES  
    ('17:51:04.777', '2018-09-08 17:51:04.777', '2018-09-08 17:51:04.777');  
INSERT INTO fractest VALUES  
    ('17:51:04.555', '2018-09-08 17:51:04.555', '2018-09-08 17:51:04.555');  
INSERT INTO fractest VALUES  
    ('17:51:04.444', '2018-09-08 17:51:04.444', '2018-09-08 17:51:04.444');  
SELECT * FROM fractest;

Also see

作者:风逝

兴趣爱好广泛,哲学 & 心理学 & 经济学 & 编程技术等方面,经常会分享读书笔记和想法,希望能够认识志同道合的朋友。你有任何看法或建议,都可以直接在文章中评论。

发表评论

您的电子邮箱地址不会被公开。