前言
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
三、对应截图
表格截图:
-Duser.timezone
jdbc:mysql
time-zone
SQL日志 控制台
接口出参
总结
- 从上面的统计, 时间都是基于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 …等等, 这个含义哈, 这个还得麻烦大家自行处理了, 汗颜, 哈哈哈, 当然也可以参考: 各个地区对应时区的网址吗以及对应的用法