The server time zone value 'xxx' is unrecognized or represents more than one time zone 问题的解决方法

1 问题描述

开发环境为 SpringBoot2 + Mysql5.6 + mysql-connector-java8。项目启动时,抛出以下错误:

Caused by: com.mysql.cj.exceptions.InvalidConnectionAttributeException: The server time zone value '?й???????' is unrecognized or represents more than one time zone. You must configure either the server or JDBC driver (via the serverTimezone configuration property) to use a more specifc time zone value if you want to utilize time zone support.
	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[?:1.8.0_91]
	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) ~[?:1.8.0_91]
	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[?:1.8.0_91]
	at java.lang.reflect.Constructor.newInstance(Constructor.java:423) ~[?:1.8.0_91]
	at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:61) ~[mysql-connector-java-8.0.17.jar:8.0.17]
	at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:85) ~[mysql-connector-java-8.0.17.jar:8.0.17]
	at com.mysql.cj.util.TimeUtil.getCanonicalTimezone(TimeUtil.java:132) ~[mysql-connector-java-8.0.17.jar:8.0.17]
	at com.mysql.cj.protocol.a.NativeProtocol.configureTimezone(NativeProtocol.java:2139) ~[mysql-connector-java-8.0.17.jar:8.0.17]
	at com.mysql.cj.protocol.a.NativeProtocol.initServerSession(NativeProtocol.java:2163) ~[mysql-connector-java-8.0.17.jar:8.0.17]
	at com.mysql.cj.jdbc.ConnectionImpl.initializePropsFromServer(ConnectionImpl.java:1301) ~[mysql-connector-java-8.0.17.jar:8.0.17]
	at com.mysql.cj.jdbc.ConnectionImpl.connectOneTryOnly(ConnectionImpl.java:958) ~[mysql-connector-java-8.0.17.jar:8.0.17]
	at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:817) ~[mysql-connector-java-8.0.17.jar:8.0.17]
	at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:447) ~[mysql-connector-java-8.0.17.jar:8.0.17]
	at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:237) ~[mysql-connector-java-8.0.17.jar:8.0.17]
	at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:199) ~[mysql-connector-java-8.0.17.jar:8.0.17]
	at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:136) ~[HikariCP-3.2.0.jar:?]
	at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:369) ~[HikariCP-3.2.0.jar:?]
	at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:198) ~[HikariCP-3.2.0.jar:?]
	at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:467) ~[HikariCP-3.2.0.jar:?]
	at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:541) ~[HikariCP-3.2.0.jar:?]
	at com.zaxxer.hikari.pool.HikariPool.(HikariPool.java:115) ~[HikariCP-3.2.0.jar:?]
	at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) ~[HikariCP-3.2.0.jar:?]
	at org.springframework.jdbc.datasource.DataSourceUtils.fetchConnection(DataSourceUtils.java:157) ~[spring-jdbc-5.1.9.RELEASE.jar:5.1.9.RELEASE]
	at org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection(DataSourceUtils.java:115) ~[spring-jdbc-5.1.9.RELEASE.jar:5.1.9.RELEASE]
	at org.springframework.jdbc.datasource.DataSourceUtils.getConnection(DataSourceUtils.java:78) ~[spring-jdbc-5.1.9.RELEASE.jar:5.1.9.RELEASE]
	at org.springframework.jdbc.support.JdbcUtils.extractDatabaseMetaData(JdbcUtils.java:319) ~[spring-jdbc-5.1.9.RELEASE.jar:5.1.9.RELEASE]
	... 67 more

2 原因

原因是未指定时区。

在 Mysql 数据库执行以下 SQL:

SELECT @@global.system_time_zone,@@global.time_zone;

运行结果:

global.time_zone 是每次连接会话的时区,默认值为 system。如果是 system,那么它就会使用 global.system_time_zone 的值,而该值是乱码,所以抛错。

3 解决

有两种解决方法,下面分别予以说明。

3.1 为 mysql-connector-java 驱动指定时区

在 mysql-connector-java 的 url 配置中,可以通过 serverTimezone 属性来指定时区。形如:

jdbc:mysql://localhost/xxx?serverTimezone=Asia/Shanghai

3.2 为 mysql 数据库配置时区

在 mysql 安装目录下的 my.ini 的 [mysqld] 配置时区:

default-time-zone='+8:00'

整个地球分为二十四时区,每个时区都有自己的本地时间。北京时区是东八区,即比通用协调时(UTC, Universal Time Coordinated) 快 8 小时,所以这里设置为 +8:00。

设置后,重启 mysql 数据库。这时,再次查询 mysql 数据库的时区,就可以看到我们刚才所设置的值啦:


建议优先配置好 mysql 数据库的全局时区。如果因为其它原因,无法配置 mysql ,再使用第一种方案,即 为 mysql-connector-java 驱动指定时区。

你可能感兴趣的:(MySQL,Java)