Java与MySQL时区
一、CST 时区混乱
CST是一个混乱的时区,它有四种含义:
- 美国标准时间 Central Standard Time (USA):
UTC-06:00
(或UTC-05:00
)。夏令时:3月11日至11月7日,使用UTC-05:00
;冬令时:11月8日至次年3月11日,使用UTC-06:00
- 澳大利亚标准时间 Central Standard Time (Australia):
UTC+09:30
- 中国标准时 China Standard Time:
UTC+08:00
- 古巴标准时 Cuba Standard Time:
UTC-04:00
中国其实也实行过夏令时,(1992年之后中国已经没有再实行过夏令时了),当实行夏令时,中国标准时间的时区偏移量就是+09:00,当非夏令时,中国标准时间的时区偏移量就是+08:00
CST在Linux、MySQL、Java中的含义:
- 在Linux或MySQL中,CST表示的是:中国标准时间(
UTC+08:00
) - 在Java中,CST表示的是:中央标准时间(美国标准时间)(
UTC-05:00
或UTC-06:00
)
注:Java 的 Date 中的CST是表示的中国标准时间
早期基准是:GMT(格林尼治标准时间)
后来基准是:UTC(协调世界时)
二、Java 时区
@Test
public void testTimeZone() {TimeZone defaultTZ = TimeZone.getDefault();TimeZone shanghaiTZ = TimeZone.getTimeZone("Asia/Shanghai");TimeZone chinaTZ = TimeZone.getTimeZone("GMT+08:00");TimeZone tokyoTZ = TimeZone.getTimeZone("Asia/Tokyo");TimeZone utc = TimeZone.getTimeZone("UTC");TimeZone gmt = TimeZone.getTimeZone("GMT");TimeZone cst = TimeZone.getTimeZone("CST");Date date = new Date(0L);SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");sdf.setTimeZone(defaultTZ);System.out.println(String.format("%-15s %-15s %s", defaultTZ.getID(), defaultTZ.getDisplayName(), sdf.format(date)));sdf.setTimeZone(shanghaiTZ);System.out.println(String.format("%-15s %-15s %s", shanghaiTZ.getID(), shanghaiTZ.getDisplayName(), sdf.format(date)));sdf.setTimeZone(chinaTZ);System.out.println(String.format("%-15s %-15s %s", chinaTZ.getID(), chinaTZ.getDisplayName(), sdf.format(date)));sdf.setTimeZone(tokyoTZ);System.out.println(String.format("%-15s %-15s %s", tokyoTZ.getID(), tokyoTZ.getDisplayName(), sdf.format(date)));sdf.setTimeZone(utc);System.out.println(String.format("%-15s %-15s %s", utc.getID(), utc.getDisplayName(), sdf.format(date)));sdf.setTimeZone(gmt);System.out.println(String.format("%-15s %-15s %s", gmt.getID(), gmt.getDisplayName(), sdf.format(date)));sdf.setTimeZone(cst);System.out.println(String.format("%-15s %-15s %s", cst.getID(), cst.getDisplayName(), sdf.format(date)));
}
控制台输出:
Asia/Shanghai 中国标准时间 1970-01-01 08:00:00
Asia/Shanghai 中国标准时间 1970-01-01 08:00:00
GMT+08:00 GMT+08:00 1970-01-01 08:00:00
Asia/Tokyo 日本标准时间 1970-01-01 09:00:00
UTC 协调世界时 1970-01-01 00:00:00
GMT 格林尼治标准时间 1970-01-01 00:00:00
CST 北美中部标准时间 1969-12-31 18:00:00
在Java中,CST表示的是:中央标准时间(美国标准时间)(UTC-05:00
或UTC-06:00
)
三、MySQL 服务端时区
- system_time_zone (系统时区):在 MySQL 启动时会检查当前系统的时区并根据系统时区设置全局参数 system_time_zone 的值,默认值一般为 CST
- time_zone (全局时区或当前会话时区)
可通过 SQL 语句查看:
mysql> show global variables like '%time_zone%';
+------------------+--------+
| Variable_name | Value |
+------------------+--------+
| system_time_zone | CST |
| time_zone | SYSTEM |
+------------------+--------+
2 rows in set (0.00 sec)
四、Java 与 MySQL 时区转换
1. jdbc 驱动
url : jdbc:mysql://127.0.0.1:3306/nginx_log?serverTimezone=GMT%2B9
对于 mysql-connector-java-8.0.18.jar,设置 jdbc 的 serverSession 时区有:
- 获得 mysql 服务端的 time_zone 值,若 time_zone 为 SYSTEM,获得 system_time_zone 的值,可叫做服务端配置的时区
- 获取 url 配置的 serverTimezone 的值,可叫做客户端配置的时区
- 若 serverTimezone 为 null,设置 serverSession 的时区是服务端的时区;若 serverTimezone 有值,设置 serverSession 的时区是客户端的时区
设置 serverSession 时区优先级:
- time_zone 是 SYSTEM,serverTimezone > system_time_zone
- time_zone 不是 SYSTEM,serverTimezone > time_zone
注:从 mysql 服务端获得 system_time_zone 若为 CST,java 中 CST 表示 UTC-05:00
或 UTC-06:00
// com.mysql.cj.protocol.a.NativeProtocol.javapublic void configureTimezone() {String configuredTimeZoneOnServer = this.serverSession.getServerVariable("time_zone");if ("SYSTEM".equalsIgnoreCase(configuredTimeZoneOnServer)) {configuredTimeZoneOnServer = this.serverSession.getServerVariable("system_time_zone");}String canonicalTimezone = getPropertySet().getStringProperty(PropertyKey.serverTimezone).getValue();if (configuredTimeZoneOnServer != null) {// user can override this with driver properties, so don't detect if that's the caseif (canonicalTimezone == null || StringUtils.isEmptyOrWhitespaceOnly(canonicalTimezone)) {try {canonicalTimezone = TimeUtil.getCanonicalTimezone(configuredTimeZoneOnServer, getExceptionInterceptor());} catch (IllegalArgumentException iae) {throw ExceptionFactory.createException(WrongArgumentException.class, iae.getMessage(), getExceptionInterceptor());}}}if (canonicalTimezone != null && canonicalTimezone.length() > 0) {this.serverSession.setServerTimeZone(TimeZone.getTimeZone(canonicalTimezone));//// The Calendar class has the behavior of mapping unknown timezones to 'GMT' instead of throwing an exception, so we must check for this...//if (!canonicalTimezone.equalsIgnoreCase("GMT") && this.serverSession.getServerTimeZone().getID().equals("GMT")) {throw ExceptionFactory.createException(WrongArgumentException.class, Messages.getString("Connection.9", new Object[] { canonicalTimezone }),getExceptionInterceptor());}}this.serverSession.setDefaultTimeZone(this.serverSession.getServerTimeZone());}
对于 mysql-connector-java-8.0.29.jar 驱动,设置 jdbc 的 serverSession 时区有:
- 获取 url 配置的 serverTimezone 的值,可叫做客户端配置的时区
- 若 serverTimezone 为 null,设置 serverSession 的时区是 java 的默认时区;若 serverTimezone 有值,设置 serverSession 的时区是客户端的时区
设置 serverSession 时区优先级:
- serverTimezone > java 默认时区
// com.mysql.cj.protocol.a.NativeProtocol.javapublic void configureTimeZone() {String connectionTimeZone = getPropertySet().getStringProperty(PropertyKey.connectionTimeZone).getValue();TimeZone selectedTz = null;if (connectionTimeZone == null || StringUtils.isEmptyOrWhitespaceOnly(connectionTimeZone) || "LOCAL".equals(connectionTimeZone)) {selectedTz = TimeZone.getDefault();} else if ("SERVER".equals(connectionTimeZone)) {// Session time zone will be detected after the first ServerSession.getSessionTimeZone() call.return;} else {selectedTz = TimeZone.getTimeZone(ZoneId.of(connectionTimeZone)); // TODO use ZoneId.of(String zoneId, Map<String, String> aliasMap) for custom abbreviations support}this.serverSession.setSessionTimeZone(selectedTz);if (getPropertySet().getBooleanProperty(PropertyKey.forceConnectionTimeZoneToSession).getValue()) {// TODO don't send 'SET SESSION time_zone' if time_zone is already equal to the selectedTz (but it requires time zone detection)StringBuilder query = new StringBuilder("SET SESSION time_zone='");ZoneId zid = selectedTz.toZoneId().normalized();if (zid instanceof ZoneOffset) {String offsetStr = ((ZoneOffset) zid).getId().replace("Z", "+00:00");query.append(offsetStr);this.serverSession.getServerVariables().put("time_zone", offsetStr);} else {query.append(selectedTz.getID());this.serverSession.getServerVariables().put("time_zone", selectedTz.getID());}query.append("'");sendCommand(getCommandBuilder().buildComQuery(null, query.toString()), false, 0);}}
综上:解决时区问题,可设置 url 中的 serverTimezone,serverTimezone 与 mysql 服务端的 system_time_zone 保持一致
2.java 与 mysql
Java 系统时区:Asia/Shanghai(东8区)
JDBC 数据库连接时区:serverTimezone=-5
MySQL 全局时区:time_zone=+08:00
Java与MySQL时区相关推荐
- java连接mysql时区修改_java连接mysql数据库时的时区设置问题(time_zone)
java在连接mysql数据库时,会由于时区设置不正确导致报以下的错误: The server time zone value '???ú±ê×??±??' is unrecognized or re ...
- java代码中设置mysql时区_关于Java中的mysql时区问题详解
前言 话说工作十多年,mysql 还真没用几年.起初是外企银行,无法直接接触到 DB:后来一直从事架构方面,也多是解决问题为主. 这次搭建海外机房,围绕时区大家做了一番讨论.不说最终的结果是什么,期间 ...
- MySql数据库记录相差14小时排错,使用Java访问Mysql数据库时出现时区异常的解决方案
最近遇到1个大坑,A系统迁移到B系统,2边系统 同1个字段 createTime 看到的不一致. 表象: A系统: 2019-6-10 17:34 B系统: 2019-6-11 .... 再次尝试: ...
- Java连接MySQL数据库时的时区问题
1.背景 通过Java代码实现向MySQL数据库中存储时间和读取时间, 2.出现的问题 Java代码中的时间点和存到数据库中的时间点不一致,并且验证Linux中的时间点是北京时间. 3.Java代码向 ...
- mysql内部时区_一文解决MySQL时区相关问题
前言: 在使用MySQL的过程中,你可能会遇到时区相关问题,比如说时间显示错误.时区不是东八区.程序取得的时间和数据库存储的时间不一致等等问题.其实,这些问题都与数据库时区设置有关,本篇文章将从数据库 ...
- The server time zone value 'Öйú±ê׼ʱ¼ä' is unrecognized 偶然遇到的mysql时区问题
因为换了个电脑用,运行时报了个很少见的异常.如下: Loading class `com.mysql.jdbc.Driver'. This is deprecated. The new driver ...
- java获取mysql时间格式化_Java与mysql的时间格式化问题,获取时间的上下午
Java与mysql的时间格式化问题,获取时间的上下午java 在项目中常常会遇到对时间进行格式化的问题,一次在对应用中发现,使用Java的SimpleDateFormat格式化时间,获取到的是上午, ...
- mysql修改系统日期_修改系统和MySQL时区
修改时间时区比想象中要简单: 各版本系统通用的方法 # cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime # cp /usr/share/zone ...
- Java 与 Mysql 时间相差八小时
Java 与 Mysql 时间相差八小时 在项目中发现,Java获取时间插入到数据库少了8小时 解决过程 最终解决方案 在项目中发现,Java获取时间插入到数据库少了8小时 其实初衷是想做定时去跑我需 ...
最新文章
- 基于深度学习的肺癌预测诊断
- 函数调用,统计数中'2’的个数
- 如何使用matplotlib绘制一个函数的图像
- ASP.NET 2.0 学习笔记 1: session 与 script 应用
- python画图横轴刻度间隔设置为3个月_Python 天气情况数据分析及可视化
- 上位机与1200组态步骤_西门子1200的HSC的应用实例!
- ONVIF协议实现1:Server端Discovery的实现详解
- sql 拼接int类型的字段_这才是SQL优化的正确姿势!
- c语言 函数 收集,c语言库函数大全--资料收集+
- DBSCAN聚类(code)
- MFC使用简单总结(便于以后查阅)
- 【前端】书签应用开发总结
- OpenCV实现监控移动侦测
- Clickhouse查询语句 sample
- nginx容器通过docker内置DNS实现动态负载
- C语言二维数组范德蒙,2、编写一个程序,实现一个3×4矩阵转置。
- 为什么局部下降最快的方向就是梯度的负方向?
- 2022年全国职业技能大赛-网络系统管理竞赛-网络模块-Ruijie-AC-SSH
- 软件质量保证和软件配置管理
- 随机数的生成【详解】
热门文章
- android手机哪家强,Android智能手机充电速度哪家强
- 2021考研英语作文石雷鹏
- sql server DateName、DatePart 函数
- 一元多项式c语言顺序存储,一元多项式相加程序(C语言)
- 关于远程连接使用完后已断开连接,服务器端仍显示用户正在连接的解决方法
- Oracle数据库一直卡在正在连接中问题解决(Windows)
- linux修改密码报错‘Authentication token manipulation error‘
- 一个ACM渣渣关于找工作的胡扯
- 【编程马拉松】【010-杨辉三角】
- Android之乐学成语