国际化软件如何保证MySQL的时间是正确的

时间戳 UNIX 时间 是没有时区概念的都是按照伦敦时间 UTC 1970年1月1日00:00:00 

时间戳 UNIX 时间 是没有时区概念的都是按照伦敦时间 UTC 1970年1月1日00:00:00

 

 

MySQL数据库存储列最好是 int64 存储 UNIX 时间 

如果展示为中国北京时间,那么如果 unix time 是 0 ,在伦敦是 1970-01-01 00:00:00 在中国是 1970-01-01 08:00:00

数据库里面存储的一定是 UTC 的也就是0

展示的话,带上时区转换 

 

1、时区

同一个时间点,比如 英国的1970-01-01 00:00:00 的那一个时刻,在东八区北京时间是:1970-01-01 08:00:00

所以,时间戳的秒数也会不同:

北京时间戳为0,对应的时间点是  1970-01-01 08:00:00

 英国的时间戳为0,对应的时间点是 1970-01-01 00:00:00

 

2、MySQL的时间存储

dateTime   没有时区概念,相当于字符串入库

timestamp    存储时,MySQL将TIMESTAMP 值从当前时区转换为UTC时间进行存储,查询时,将数据从UTC转换为检索的当前时区。(其他类型(如DATETIME)不会发生这种情况。)

参考链接:https://blog.csdn.net/m0_38072683/article/details/105011313

 时区  show variables like "%time_zone";   

system_time_zone -- 系统时区

 

3、Java连接MySQL获取时间如何展示

 

我们想要的情况:

如果数据库之中存储的时间是  北京时间 1970-01-01 08:00:00 

如果是北京的用户,看到的时间是 1970-01-01 08:00:00 GMT+8

如果是英国的用户,看到的时间是 1970-01-01 00:00:00 UTC

 (当然用户只会看到不带时区的日期时间部分)

 

4、影响Java使用mybatis查询时间,然后转json数据输出,影响时区的有哪几个配置

1. spring.datasource.url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC&useSSL=false

(连接配置的时区信息 ,CST 北京时间)

2. @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm")

(Jackson解析数据的时区配置)

 

5、时区错误显示的情况有哪些

情况一:北京的用户,在08:00操作了一条数据,存储了一条 GMT+8  2020-01-01 08:00:00 的时间点,在MySQL之中存储时间的数据格式是 datetime

英国的用户读取这条数据时候( 2020-01-01 02:00:00 ),拿到操作时间也是 2020-01-01 08:00:00 那么明显是错误的,出现错误的原因是没有将时间转为 UTC 2020-01-01 00:00:00

 

情况二:北京的用户存储的时间是 GMT+8 2020-01-01 08:00:00 存储的时间格式是timestamp(有时区)

英国的用户读取数据时候 orm 实体类User.class之中的字段属性值也是对的,但是转jackson的时候错误配置了

spring.jackson.date-format: yyyy-MM-dd HH:mm:ss
spring.jackson.time-zone: GMT+8

也就是对于jackson而言,将 UTC 2020-01-01 00:00:00 转成了 GMT+8 2020-01-01 08:00:00 (时区信息没展示)

 

6、如何保证数据正常

spring.datasourc.url 配置timezone为UTC,这样与MySQL的时间戳是UTC,北京的用户时间 CST 2020-01-01 08:00:00 在MySQL之中的时间是 UTC 2020-01-01 00:00:00 

MySQL的时区可以通过 show variables like "%time_zone";  看到

url里面的时区只是决定了从 java过去的时间格式和从MySQL查询回来的时间,带上了对应的时区。

不管MySQL还是spring.datasource.url都固定为UTC即可避免,spring.datasource.url 存储 GMT+8  2020-01-01 08:00:00到MySQL,却被认为是 UTC 2020-01-01 08:00:00

 

jackson的time-zone是服务器当前的时区(北京的用户对应北京的时区,英国的用户对应英国的时区) 

 

 

 spring的mariadb连接配置的timezone是 UTC 会导致 北京时间 08:00 在MySQL之中存储的数据是 00:00 吗?

 

 spring的mariadb连接配置的timezone是 Asia/Shanghai 会导致我存储的时间就是 GTM+8 2022-01-01 08:00 ,如果是datetime格式那么存储的就是 2022-01-01 08:00

如果是UTC那么存储的就是 2022-01-01 00:00:00 (即使服务器是北京时间 08:00:00)

]

 

 

 

分别以 UTC 和 Asia/Shanghai 存储进字段之中,当UTC时候,会将当前 new Date的北京时间转为 UTC时间存储;

 

读取的时候,当spring.maridb的url的serverTimezone 为UTC的时候,上面的正常

为Asia/Shanghai的时候,下面的正常,所以存储进去和读取的时候请保持一致;

 

 

原因是:

读取的时候并且MySQL会默认其时区为Java会话带过来的时区,所以使用UTC读取的时候,上面的第二行(这一行写入的实际时间是东八区的时间,但是被当成了UTC)的时间读取出来后变成了

Thu Apr 21 06:24:26 CST 2022

也就是加了8个小时,也就是 MySQL认为它是  UTC 2022-04-20 22:24:26   而java又要这个时间点的东八区的时间

那么就是  CST 2022-04-21 06:24:26

 

 参考博客:

 

 UTC 和 GMT 什么关系? https://www.zhihu.com/question/27052407

记住几个关键字 UTC 、GMT+8

 

 

 

 

posted @   许伟强  阅读(1393)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
点击右上角即可分享
微信分享提示