前言

UTC: 全球标准时间
GMT: 格林威治标准时间
我不知道该怎么解释UTC和GMT的关系, 我个人的理解是:
UTC+0=GMT+0,UTC+8=GMT+8 但是UTC不是GMT, GMT也不是UTC

这里会涉及到五个时区需要注意:

  • JVM时区
  • MySQL时区
  • 系统时区
  • jdbc链接时区
  • jackson指定时区

测试数据 + 结论 + 表格截图


提示:表格中列出的名称不是很规范, 大家看一下对应的截图, 就知道了 一、测试数据

下面会列出一个表格, 就表格中的一些内容先做一下讲解:
如果这里我表达的不是很清楚, 文章的下面也列出了对应的截图

MySQL系统:        安装MySQL的系统时间, 查询命令: date -R
MySQL:           数据库的时区配置, 查询命令: SHOW VARIABLES LIKE '%time_zone%'
jdbc:mysql:      jdbc:mysql://*****&serverTimezone=GMT
-Duser.timezone: JVM的时区
time-zone:       spring.jackson.time-zone
SQL日志:          打印的SQL语句, 以及对应的结果
控制台:           当我们查询出来的数据, 放入entity或者map集合, get出来的值
接口出参:         比如postman调用接口, 返回的数据
MySQL系统 MySQL jdbc:mysql -Duser.timezone time-zone SQL日志 控制台 接口出参 时间是否一致
+0800 CST GMT%2B8 GMT+8 GMT+8 2019-11-22 10:12:13 2019-11-22 10:12:13 2019-11-22 10:12:13
+0800 CST GMT%2B8 GMT+8 GMT+2 2019-11-22 10:12:13 2019-11-22 10:12:13 2019-11-22 04:12:13
+0800 CST GMT%2B8 UTC GMT+8 2019-11-22 10:12:13 2019-11-22 02:12:13 2019-11-22 10:12:13
+0800 CST GMT%2B8 UTC GMT+2 2019-11-22 10:12:13 2019-11-22 02:12:13 2019-11-22 04:12:13
+0800 CST GMT%2B8 GMT+2 GMT+8 2019-11-22 10:12:13 2019-11-22 04:12:13 2019-11-22 10:12:13
+0800 CST UTC GMT+8 GMT+8 2019-11-22 10:12:13 2019-11-22 18:12:13 2019-11-22 18:12:13
+0800 CST UTC UTC GMT+0 2019-11-22 10:12:13 2019-11-22 10:12:13 2019-11-22 10:12:13
+0800 CST UTC UTC GMT+8 2019-11-22 10:12:13 2019-11-22 10:12:13 2019-11-22 18:12:13
+0800 CST GMT%2B2 GMT+3 GMT+4 2019-11-22 10:12:13 2019-11-22 11:12:13 2019-11-22 12:12:13
+0800 CST GMT-2 GMT-3 GMT-4 2019-11-22 10:12:13 2019-11-22 09:12:13 2019-11-22 08:12:13
+0000 UTC GMT-2 GMT-3 GMT-4 2021-07-21 11:51:16 2021-07-21 10:51:16 2021-07-21 09:51:16

二、结论

通过上面的数据, 我得出一个结论:

SQL日志=
数据库保存的数据对应的时间

控制台=
((SQL日志)(2019-11-22 10:12:13)) - (jdbc:mysql)(GMT%2B8)) + (-Duser.timezone)(GMT+8))
= MySQL保存时间 - jdbc链接指定时区 + jvm时区
= 2019-11-22 10:12:13 - 8 + 8
= 2019-11-22 10:12:13

接口出参=
((SQL日志)(2019-11-22 10:12:13)) - ((jdbc:mysql)(GMT%2B8)) + ((time-zone)(GMT+8))
= MySQL保存时间 - jdbc链接指定时区 + jackson配置时区
= 2019-11-22 10:12:13 - 8 + 8
= 2019-11-22 10:12:13


三、对应截图

表格截图:

SpringBoot时区配置_springboot


-Duser.timezone

SpringBoot时区配置_java_02


jdbc:mysql

SpringBoot时区配置_java_03


time-zone

SpringBoot时区配置_java_04


SQL日志 控制台

SpringBoot时区配置_java_05


接口出参

SpringBoot时区配置_mysql_06


总结
  • 从上面的统计, 时间都是基于MySQL保存的这个时间, 做对应的±操作
  • 在做涉及时区的项目, 如果就是一个地区, 那就按当地时区设置就行. 但是如果是同一个项目, 多个地区运行, 服务器就统一设置UTC时间, 包括数据库UTC, JVM时区UTC, time-zone也就是展示给用户看的时间, 配置对应的GMT±
  • 我没有去看对应的源码, 只是写了一个简单的测试用例得出的结果

  • new Date() = UTC + (-Duser.timezone)
  • 上面表格中列出的, 是不支持UTC±的写法, 比如-Duser.timezone=UTC-8是识别不出来的
    但是-Duser.timezone=GMT-8或者-Duser.timezone=UTC是可识别的
  • 各个地区对应时区的网址吗以及对应的用法: https://www.ibm.com/docs/zh/was/9.0.5?topic=ctzs-time-zone-ids-that-can-be-specified-usertimezone-property
  • 根据地址查时区: http://time.tianqi.com/dubai/
  • 具体UTC GMT CST PRT WET CET ECT …等等, 这个含义哈, 这个还得麻烦大家自行处理了, 汗颜, 哈哈哈, 当然也可以参考: 各个地区对应时区的网址吗以及对应的用法