紧接上篇MySQL时区全解,date_time 和 timestamp 区别,GMT、UTC、CST、东八区分别指什么? ,我在里面分享了
datetime
和timestamp
的区别CURRENT_TIMESTAMP
和ON UPDATE CURRENT_TIMESTAMP
在创建表时的使用- GMT、UTC、CST、东八区相关科普,学习数据库时区和数据库服务器时区的控制参数
最后找出数据库时区是 CST ,但并非中国标准时间,导致存在异常,但没法解释我的问题,因为只有我的接口插入时间有问题。如果是数据库时区的原因,那所有插入的时间应该都存在问题。
在继续往下分享之前,先处理一个前面故意绕过的知识,修改数据库时区,前文我修改数据库时区的方法很简单粗暴
set time_zone='+08:00';
但这个设置只是临时的,而且只是会话级别,只要我们关闭这次数据库连接,重新进去,它的时区又变成原来的。
如果想更加深刻设置,用如下命令
set global time_zone = '+8:00';
flush privileges;
这种修改属于全局修改,就算关闭连接重新进去,依然生效。但如果将数据库服务停止,再次启动,它的数据库时区又回到原来的。
如果想永久修改,要修改配置文件 my.cnf(linux),在 [mysqld] 节下增加 default-time-zone = ‘+08:00’。这种修改就算重启数据库服务也能生效。
这种修改效力很强大,但还不是最强的,优先级最高的是 JDBC 配置的时区。
serverTimezone=Asia/Shanghai
只要在这配置时区,那上面所有设置都不会生效,以 JDBC 的时区为准。
比如我将数据库时区修改成 GMT+0 标准时间
set global time_zone = '+00:00';
flush privileges;
然后再用 JDBC 东八区时间(中国标准时间)去插入时间
serverTimezone=Asia/Shanghai
Java 代码如下
entity.setUpdateTime(new Date());
entity.setCreateTime(new Date());
插入到表里的时间还是东八区时间,也就是中国标准时间。比如现在是中国时间2021-11-16 20:24:02
,表里的时间也是这个值。
但这里有点特殊情况特别要注意,这里的时间是我们用代码通过 JDBC 插入的,如果我们不生成时间向表里插入呢?
比如将上面两行代码注释,因为表里字段都用了默认时间设置CURRENT_TIMESTAMP
,所以就算没传值,数据库还是会给我们自动生成一个当前默认时间,但这里生成的时间就是按照数据库时区生成的,因为数据库是 GMT+0 时区,这里会变成2021-11-16 12:24:02
,这就和中国时间相差 8 小时了。
很明显,找到我的问题,我插入时间时并没手动在代码生成插入,而是数据库自动生成的。根据上篇博客中提到的,虽然都是 CST ,但中国和美国之间相差 13 个小时。
中国标准时间 China Standard Time UTC+08:00
美国中部时间 Central Standard Time (USA) UTC-05:00 / UTC-06:00
现在来做个总结:
1、JDBC 时区和数据库时区一定要一致
2、表里时间可以配置默认值CURRENT_TIMESTAMP
,避免因为极端情况导致时间是 null,程序崩溃,但时间一定要通过 JDBC 插入,不能依赖数据库自动生成。
3、根据阿里规范,可以将createTime
和updateTime
放到基类,然后直接默认获取当前时间,这样可以避免忘记。
本文由老郭种树原创,转载请注明:https://guozh.net/mysql-time-zone-2/