Mysql 时区差8小时的多种问题 统统解决

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 RDS PostgreSQL,集群系列 2核4GB
简介: Mysql 时区差8小时的多种问题 统统解决

背景


最近在开发【Java面试 | 笑小枫】小程序,便发现老是有人半夜偷偷刷题,如下图所示:


image-20230321205840646.png


现在都这么卷了吗?大半夜的都不睡觉了吗?还在撸题~越想越不对,赶紧看了一下,发现自己录入题目的时间也好多都在凌晨。

好家伙,秒懂,时区错了。错就错了吧,影响也不大。

直到现在出现了每日签到的功能,好吧顺手改一下,反正也不难。都改了,顺手整理篇博客吧。


知识点


UTC:Coordinated Universal Time 协调世界时。

GMT:Greenwich Mean Time 格林尼治标准时间。(在协调世界时意义上的0时区,即GMT = UTC+0)

中国的时间是【东八区】,比GMT多八个小时,即 GMT+8(或UTC+8,但习惯上还是用GMT+8)


代码中常见的三种时间差错问题


【我遇到的】本地获取的时间没有错,存入数据库的时候时间相差8小时


mybatis将本地的数据传入到mysql数据库服务器的时候,服务器会对数据进行检测,会把date类型的数据自动转换为mysql服务器所对应的时区,即0时区,所以会相差8小时。

解决方案:

  • 在数据库链接上添加serverTimezone=GMT%2B8

723296c9d6e498a3f4ef2235f7f3df60.png


java下使用 new date()获取的时间会和真实的本地时间相差8小时


new date()调用的是jvm时间,而jvm使用的时间默认是0时区的时间,即:和北京时间将会相差8小时。


解决方案:


  • 手动设置jvm时间:将时间改为第8时区的时间:
  • 如果是springboot项目,可以面向切面加上这个,或者启动main类上加上如下代码:


TimeZone.setDefault(TimeZone.getTimeZone("GMT+8"));


数据库时间没有错,获取到了后端,之后返回给前端相差8小时


springboot中对加了@RestController或者@Controller+@ResponseBody注解的方法的返回值默认是Json格式,所以,对date类型的数据,在返回浏览器端时,会被springboot默认的Jackson框架转换,而Jackson框架默认的时区GMT(相对于中国是少了8小时)。所以最终返回到前端结果是相差8小时。


解决方案:


  • 将spring的json构造器的时区改正即可,在application.yml文件中添加:


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


  • 可以使用注解,在entity实体类的date数据上添加注解,那么数据库传回的data数据要转换为json格式的时候就是北京时间了,再次传回到前端的时候,也不会出现时区问题。
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
private Date updateDate;


数据库代码时区的问题


以上说的都是代码中时间的问题,还有一种情况,就是sql使用NOW()获取时间,这种写法太可恶了。强烈不推荐


这种情况使用的是数据库的时间,首先我们看一下数据库时间


select NOW();


image-20230321215559765.png


如果和当前时间一致,那么恭喜你,没问题。

如果比当前时间少8小时,那么依旧恭喜你,你穿越了。

5c3f0aca730e0a0049889c8ef1894cb5.png


言归正传,如果比当前时间少8小时,该怎么处理呢?


通过Sql命令修改,临时生效


本方法的优点是,生效快,不需要重启数据库;缺点是重启数据库后配置失效。


  1. 首先检查下Mysql系统时区
show variables like '%time_zone%';



image-20230321215721287.png

  1. 设置时区


-- 修改mysql全局时区为北京时间,即我们所在的东8区
set global time_zone = '+08:00'; 
-- 修改当前会话时区,不然需要重新打开会话才会生效
set time_zone = '+08:00';


  1. 立即刷新生效
flush privileges;


然后再执行一下我们的select NOW();查看一下时间,OK,时间一致


image-20230321220030720.png



通过配置文件来进行修改,永久性生效


本方法的优点是永久性生效,缺点是需要重启数据库


修改mysql的配置文件。linux系统上是my.cnf文件,window系统是my.ini


在[mysqld]区域中加上 default-time_zone = ‘+8:00’


重启mysql使新时区生效


总结


本文到这里就结束了。总结一下吧


  1. 代码中常见的数据问题是,程序中正常,保存到数据库中差8小时,这种情况用在数据库连接中添加serverTimezone=GMT%2B8
  2. Java下使用 new date()获取的时间会和真实的本地时间相差8小时,这个需要修改JVM时区,正常很少见
  3. 数据库时间没有错,获取到了后端,之后返回给前端相差8小时,可以通过设置json转换的时区来进行调整
  4. 修改数据库的时区,可以通过命令临时修改和通过配置文件永久性修改



61dfe88cc117f1402d2b241fc3971439.png

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
SQL NoSQL 关系型数据库
docker设置mysql、redis等容器的时区
问题:现在本地docker的mysql容器时区不对,需要为中国的时区
290 0
|
4月前
|
消息中间件 关系型数据库 MySQL
实时计算 Flink版产品使用问题之使用CTAS同步MySQL到Hologres时出现的时区差异,该如何解决
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStream API、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。
|
6月前
|
数据采集 DataWorks 监控
DataWorks产品使用合集之mysql-cdc读取数据写入到datahub中,datahub如何转换时区
DataWorks作为一站式的数据开发与治理平台,提供了从数据采集、清洗、开发、调度、服务化、质量监控到安全管理的全套解决方案,帮助企业构建高效、规范、安全的大数据处理体系。以下是对DataWorks产品使用合集的概述,涵盖数据处理的各个环节。
62 1
|
6月前
|
关系型数据库 MySQL Go
Mysql查看数据库时区并设置时区
Mysql查看数据库时区并设置时区
459 0
|
7月前
|
SQL 关系型数据库 MySQL
实时计算 Flink版操作报错之遇到MySQL服务器的时区偏移量(比UTC晚18000秒)与配置的亚洲/上海时区不匹配,如何解决
在使用实时计算Flink版过程中,可能会遇到各种错误,了解这些错误的原因及解决方法对于高效排错至关重要。针对具体问题,查看Flink的日志是关键,它们通常会提供更详细的错误信息和堆栈跟踪,有助于定位问题。此外,Flink社区文档和官方论坛也是寻求帮助的好去处。以下是一些常见的操作报错及其可能的原因与解决策略。
|
7月前
|
关系型数据库 MySQL Java
MySQL与服务器时区问题实践总结
MySQL与服务器时区问题实践总结
972 0
|
JSON 关系型数据库 MySQL
Mysql时区差8个小时问题解决
Mysql时区差8个小时问题解决
321 1
|
关系型数据库 MySQL Java
TimeZone-datetime在JVM时区和MySQL Session时区的转换
TimeZone-datetime在JVM时区和MySQL Session时区的转换
172 0
|
关系型数据库 MySQL Java
MySQL 数据库时区设置方法,“The server time zone value ‘�й���׼ʱ��‘ is unrecognized or represents ...” 问题解决
MySQL 数据库时区设置方法,“The server time zone value ‘�й���׼ʱ��‘ is unrecognized or represents ...” 问题解决
504 0
|
关系型数据库 MySQL
Mysql修改时区(时间差8小时)
Mysql修改时区(时间差8小时)
Mysql修改时区(时间差8小时)