javamysql时区_关于Java中的mysql时区问题详解前⾔
话说⼯作⼗多年,mysql 还真没⽤⼏年。起初是外企银⾏,⽆法直接接触到 DB;后来⼀直从事架构⽅⾯,也多是解决问题为主。
这次搭建海外机房,围绕时区⼤家做了⼀番讨论。不说最终的结果是什么,期间有同事认为 DB 返回的是 UTC 时间。
这⾥简单做个验证,顺便看下时区的问题到底是如何处理。
环境
openjdk version “1.8.0_242”
mysql-connector-java “8.0.20”
mysql “5.7” 时区 TZ=Europe/London
本地时区 GMT+8
创建个简单的库test及表user, 表结构如下:
CREATE TABLE `user` (
`name` varchar(50) NOT NULL,
`birth_date` timestamp NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=latin1
插⼊⼀条测试数据:
mysql> insert into `user`
-> values ('Tom', time('2020-05-15 08:00:00'));
Query OK, 1 row affected (0.01 sec)
mysql> select * from user;
+------+---------------------+
| name | birth_date |
+------+---------------------+
| Tom | 2020-05-14 08:00:00 |
+------+---------------------+
1 row in set (0.00 sec)
测试代码:
Connection conn = Connection("jdbc:mysql://localhost:3306/test?useSSL=false", "root", "root");
Statement stmt = ateStatement();
ResultSet rs = ResultSet();
while (rs.next()) {
Timestamp timestamp = rs.getTimestamp("birth_date");
System.out.LocalDateTime().toString());
使⽤会话中的服务端时区进⾏服务端时区。会话初始化时会进⾏时区的确认,⽐如前⾯获取的到BST。确认时区的逻辑在
NativeProtocol#configureTimezone()中:
public void configureTimezone() {
#从mysql的响应获取 time_zone 和 system_time_zone 的设置
String configuredTimeZoneOnServer = ServerVariable("time_zone");
if ("SYSTEM".equalsIgnoreCase(configuredTimeZoneOnServer)) {
configuredTimeZoneOnServer = ServerVariable("system_time_zone");
}
#从 jdbc url 参数 serverTimezone 获取时区
String canonicalTimezone = getPropertySet().getStringProperty(PropertyKey.serverTimezone).getValue();
if (configuredTimeZoneOnServer != null) {
//如果 jdbc url 中未通过 serverTimezone 指定时区。则从TimeZoneMapping.properties中获取mysql 回传的时区缩写对应的标准时区,⽐如此处的 BST => Europe/London
//会出现⽆法映射的情况,不如 CEST ⽆法映射到 => Europe/Berlin,可以指定⾃定义的 Properties ⽂件进⾏映射
// user can override this with driver properties, so don't detect if that's the case
if (canonicalTimezone == null || StringUtils.isEmptyOrWhitespaceOnly(canonicalTimezone)) {
mysql下载后为啥localhost打不开try {
canonicalTimezone = CanonicalTimezone(configuredTimeZoneOnServer, getExceptionInterceptor());
} catch (IllegalArgumentException iae) {
ateException(WrongArgumentException.class, Message(), getExceptionInterceptor());
}
}
}
//如果 jdbc url 中通过 serverTimezone 指定了时区,则优先使⽤该时区
if (canonicalTimezone != null && canonicalTimezone.length() > 0) {
this.serverSession.TimeZone(canonicalTimezone));
//
// The Calendar class has the behavior of mapping unknown timezones to 'GMT' instead of throwing an exception, so we must check
//
if (!canonicalTimezone.equalsIgnoreCase("GMT") && ServerTimeZone().getID().equals("GMT")) {
ateException(WrongArgumentException.class, String("Connection.9", new Object[] { canonicalTimezone }),
getExceptionInterceptor());
}
}
}
关于 serverTimezone 的官⽅说明
Override detection/mapping of time zone. Used when time zone from server doesn't map to Java time zone
修改⼀下 jdbc url,通过serverTimezone指定时区为 GMT+8:jdbc:mysql://localhost:3306/test?
serverTimezone=GMT%2B8&useSSL=false
再次执⾏代码:
2020-05-14T08:00
总结
到此这篇关于关于Java中mysql时区问题的⽂章就介绍到这了,更多相关Java中mysql时区问题内容请搜索我们以前的⽂章或继续浏览下⾯的相关⽂章希望⼤家以后多多⽀持我们!
本⽂标题: 关于Java中的mysql时区问题详解

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。