一些背景:

我有一个运行在Tomcat 7上的Java 1.6 webapp。数据库是MySQL 5.5。以前,我使用Mysql JDBC驱动程序5.1.23连接到数据库。一切正常。我最近升级到Mysql JDBC驱动程序5.1.33。升级后,Tomcat在启动应用程序时会引发此错误。

WARNING: Unexpected exception resolving reference
java.sql.SQLException: The server timezone value 'UTC' is unrecognized or represents more than one timezone. You must configure either the server or JDBC driver (via the serverTimezone configuration property) to use a more specifc timezone value if you want to utilize timezone support.


为什么会发生这种情况?

评论

您的JDBC URL是什么样的?

检查我的答案stackoverflow.com/a/44720416/4592448。我认为这是最好的答案)

#1 楼

显然,要使MySQL JDBC驱动程序的5.1.33版与UTC时区一起使用,必须在连接字符串中显式指定serverTimezone

 jdbc:mysql://localhost/db?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC
 


评论


根据文档,当使用useLegacyDatetimeCode = false时,useJDBCCompliantTimezoneShift无效。因此,那里并不需要...

–matof
15年11月27日在8:15

This solves my error. Additional note, escape the & with & in persistence.xml file :

– pdem
Apr 18 '16 at 16:14

那是不对的。 useLegacyDatetimeCode = false的点是不必指定serverTimezone,因此客户端可以更正时区差异。这是该版本的MySQL客户端中的错误。

–antgar9
16-10-31在11:14

该解决方案破坏了格林尼治标准时间以外的时区。我认为正确的解决方案在下面被低估了

– DuncanSungWKim
17年12月13日在20:40



解决方案适用于8.0.17。发生了新的MySQL安装。不能相信这个错误在这么多年之后还没有得到修复。

–蒂尔曼·豪舍(Tilman Hausherr)
19年8月28日在18:37

#2 楼

我已经通过配置MySQL解决了这个问题。

SET GLOBAL time_zone = '+3:00';

评论


如果您使用的是MSK时区,则为+3,则可以使用以下作为数据库地址:jdbc:mysql:// localhost / db?useUnicode = true&useJDBCCompliantTimezoneShift = true&useLegacyDatetimeCode = false&serverTimezone = Europe / Moscow。看起来mysql-connector无法识别短时区名称。

–宝贝
17-2-27在14:16



当夏令时改变时钟时,您会怎么做?

–isapir
18-10-8在21:33

在mysql 8.0中,您可以调用“ setpersist time_zone ='+00:00';”将其永久设置为UTC,而无需编辑my.cnf或重新启动服务器。见mysqlserverteam.com/…

– ccleve
19年3月19日在17:07

如果通过唯一的手动SQL查询进行设置,则此设置将恢复为数据库重新启动后的原始值。

– CBA110
19年7月6日在15:27

确实有效-请记住修改本地时区字符串,以代替+3 SET GLOBAL time_zone ='+3:00';

– Pravin
6月4日5:33



#3 楼

在阅读了关于该主题的几篇文章之后,测试了不同的配置,并基于我所了解的来自mysql bug线程的一些见解:


服务器时区对于转换日期尤其重要。存储在数据库中的应用服务器所在的时区。还有其他含义,但这是最引人注目的
GMT x UTC时区系统。 GMT诞生于19世纪后期,可以在标准时间和夏季时间之间切换。此属性可能导致数据库服务器转换为夏季时间,而应用程序没有注意到它的情况(也许还有其他复杂情况,但我没有进一步研究)。 UTC不会随时间变化(在0度经度处,它总是在平均太阳时间的1秒钟之内)。
serverTimeZone定义在mysql jdbc连接器5.1版之前引入。直到版本8为止,可以使用useLegacyDatetimeCode=true忽略它,将其与useJDBCCompliantTimezoneShift=true结合使用将使应用程序获得每个连接上的数据库时区。在这种模式下,GMT时区(例如“ British Summer Time”)将转换为内部java / JDBC格式。可以在.properties文件中定义新的时区,例如此版本。

从jdbc驱动程序版本8开始,删除了自动时间匹配(useJDBCCompliantTimezoneShift)和旧时间格式(useLegacyDatetimeCode)(请参阅mysql jdbc连接器更新日志)。因此设置这2个参数无效,因为它们被完全忽略(新的默认值为useLegacyDateTimeCode=false
这样,如果任何时区(应用程序/数据库服务器)的格式都不为'UTC +,则设置serverTimezone为必选xx”或“ GMT + xx”
将服务器时间设置为UTC不会产生影响(例如,使用jdbc:mysql://localhost:3306/myschema?serverTimezone=UTC,即使您的应用程序/数据库服务器不在此时区中也是如此。重要的是应用程序连接字符串+数据库要与相同时区同步。简而言之,只需在数据库服务器上将serverTimezone = UTC设置为不同的时区,即可移动从数据库中提取的任何日期。

可以使用my.ini或MySQL默认时区设置为UTC + 0或通过添加行default-time-zone='+00:00'(此StackOverflow帖子中的详细信息)添加my.cnf文件(分别为Windows / linux)
自动为AWS(亚马逊网络服务)上配置的数据库分配UTC + 0默认时间(请参阅此处的AWS帮助页面)


评论


好的答案,谢谢。各种项目符号都很有用。我建议将默认时区='+00:00'放入自制的/usr/local/etc/my.cnf文件中。似乎=周围的空格很重要,因此您可以编辑该项目符号以包含它们。

–马克·爱丁顿
19年4月24日在2:46

#4 楼

如果使用的是Maven,则可以在pom.xml中设置另一个MySQL连接器版本(我遇到了相同的错误,所以我从6.0.2更改为5.1.39):

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.39</version>
</dependency>


如另一个答案中所述,此问题已在6.0.3或更高版本中修复,因此您可以使用更新的版本:

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>6.0.3</version>
</dependency>


Maven会自动保存pom.xml文件后,重新生成项目。

评论


对于那些下载了mysql-connector-java / 6->的人,只需下载例如mysql-connector-java / 5.1.20,它应该可以工作。谢谢!

–组合
16年11月24日在18:36

应避免降级。此外,它仍未在6.0.6中修复。更好地使用上述解决方案

– phil294
17年4月4日在14:44

即使使用最新的jar,我也遇到相同的错误[mysql-connector-java-6.0.5.jar:6.0.5]

–user2478236
17年9月19日在14:56

我什至在8.0.12中也有

– Robert Niestroj
18年8月16日在12:14

8.0.13给出了相同的错误。 5.1.47但是对我有用。

–本地主机
18-10-25在12:03

#5 楼

连接字符串的设置应如下所示:

jdbc:mysql://localhost/db?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC


如果要在xml文件(例如persistence.xmlstandalone-full.xml等)中定义连接,则应设置为&应该使用&amp;或使用CDATA块。

评论


那是不对的。 useLegacyDatetimeCode = false的点是不必指定serverTimezone,因此客户端可以更正时区差异。

–antgar9
16-10-12在17:49

这对我使用phpStorm 2019.1.4连接到MySQL 5.7很有用。

– moult86
5月19日17:33

#6 楼

我解决了将以下连接字符串放在URL中的问题

jdbc:mysql://localhost:3306/db?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC


评论


那是不对的。 useLegacyDatetimeCode = false的点是不必指定serverTimezone,因此客户端可以更正时区差异。

–antgar9
19年4月16日在12:13

#7 楼

这是从5.1.33版本到5.1.37版本的mysql-connector-java中的错误。
我在这里报告了该错误:http://bugs.mysql.com/bug.php?id=79343

编辑:
此问题已从mysql-connector-java 5.1.39中更正。

它是loadTimeZoneMappings方法中TimeUtil类的错字,该错字引起NPE定位/ com /mysql/jdbc/TimeZoneMapping.properties文件。如果您查看代码,则该文件应位于TimeUtil类加载器中,而不是TimeZone中:

使用日期时自动。因此,它可以帮助您精确地不必在每个部分中指定时区。尽管使用serverTimeZone参数是一种解决方法,但在发布补丁程序的同时,您可以像我一样尝试更好地自行更正代码。


如果它是独立应用程序,则可以尝试在代码中添加
更正的com / mysql / jdbc / TimeUtil类,并注意
jar加载顺序。这可以帮助您:
https://owenou.com/2010/07/20/patching-with-class-shadowing-and-maven.html
如果是Web应用程序,更简单的解决方案是创建您自己的
mysql-connector-java-5.1.37-patched.jar,直接将.class替换为原始jar。


评论


亲爱的,感谢您的举报。很高兴有人能够确定该错误。您知道修复程序何时发布吗?

– bluecollarcoder
16-2-9在18:19



您建议的解决方案很棒,但是我认为修改驱动程序源和管理Maven依赖关系对于大多数人来说可能太烦人了。

– bluecollarcoder
16年2月9日在18:21

@Gili自版本6.0.6起未修复

–Imme22009
17年8月21日在1:45

该错误仍存在于8.0.11中

–约翰·利特尔
19年4月5日在22:40

@JohnLittle我在8.0.15中也遇到了这个问题,但是它不再是由错误引起的。时区已正确加载,但是TimeZone.getAvailableIDs()和TimeZoneMapping.properties中均未包含CET和CEST(这些时区给我带来了麻烦),因此此解决方案在这里无济于事。解决方案可能是设置为serverTimezone = Europe / Berlin

– JPT
19年4月13日在11:52

#8 楼

只需在application.properties上添加serverTimeZone = UTC即可。 spring.datasource.url=jdbc:mysql://localhost/db?serverTimezone=UTC

评论


尝试从具有EDT时区的MacOS连接到MySQL时,出现异常。这个解决方案对我有用。只需在JDBC URL的末尾添加?serverTimezone = UTC就足够了。

– RafiAlhamd
7月10日7:42



我正在使用Spring Boot 2.3.1和mysql Connector 8.0.21,这对我有用。

–斯潘塞·斯图尔特
7月24日15:57



#9 楼



我在[mysqld]部分的mysql配置文件中添加了
default_time_zone='+03:00'



并重新启动mysql服务器:

sudo service mysql restart



我的UTC时区+03:00。

操作系统ubuntu 16.04上配置文件的路径:

/etc/mysql/mysql.conf.d/mysqld.cnf


警告:如果您的时区有夏季和冬季。如果更改时间,则必须在配置中更改UTC。一年中两次(通常)或使用SUDO设置CRONTAB。

我的网址jdbc连接:

"jdbc:mysql://localhost/java"


评论


几乎在所有生产用例中,必须重新启动Mysql基本上都是无法启动的。涉及复制时,这甚至成为一个问题。

– bluecollarcoder
17年6月26日在16:53

@bluecollarcoder仅需要在[mysqld]部分添加。如果没有[mysqld]部分,则添加该部分。我的配置示例pastebin.com/j4F7t2KS

– Fortran
17-6-27在14:08



我将Linux服务器的/ etc / localtime从/ usr / share / zoneinfo / US / Pacific更新到了/ usr / share / zoneinfo / America / Los_Angeles,然后重新启动了mysql服务,这为我解决了这个问题。

–vinnyjames
19年1月31日在22:18

就我提供的语法而言,重新启动时出现错误,正确的语法是:根据此答案,默认为time-zone ='+ 03:00'。也来自DBeaver。

– wscourge
19-4-4在5:15



如果您必须告诉公司中的每个开发人员更改其MySQL配置,则不适当:)

–pheromix
19年4月5日在14:39

#10 楼

上面的程序将生成该时区错误。

在您的数据库名称之后,您必须添加以下内容:?useTimezone=true&serverTimezone=UTC。完成代码后,您的代码将正常运行。

祝您好运:)

#11 楼

我有同样的问题,我解决了,仅将“?serverTimezone = UTC”附加到我的字符串连接中。



sinossi我的问题:

java.sql.SQLException:服务器时区值“ CEST”无法识别或代表多个时区。如果要利用时区支持,则必须配置服务器或JDBC驱动程序(通过serverTimezone配置属性)以使用更特定的时区值。

my dbDriver = com.mysql.jdbc.Driver

my jar = mysql-connector-java-8.0.12.jar

my java = 1.8

my tomcat = Apache Tomcat Version 8.5.32

my MySql server = MySql ver.8.0.12 


#12 楼

我在数据库端执行了以下操作。

mysql> SET @@global.time_zone = '+00:00';

mysql> SET @@session.time_zone = '+00:00';

mysql> SELECT @@global.time_zone, @@session.time_zone;


我正在使用服务器版本:8.0.17-MySQL Community Server-GPL

源: https://community.oracle.com/thread/4144569?start=0&tstart=0

#13 楼

您可以在Maven依赖项中使用MySQL连接器,

 <dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.14</version>
</dependency>
 


然后需要设置application.properties文件中正确的参数,

spring.datasource.url=jdbc:mysql://localhost:3306/UserReward?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC
spring.datasource.username=testuser
spring.datasource.password=testpassword
# MySQL driver
spring.datasource.driverClassName=com.mysql.jdbc.Driver
spring.jpa.database-platform=org.hibernate.dialect.MySQL5Dialect


#14 楼

解决serverTimezone问题所需的一切:

String url = "jdbc:mysql://localhost:3306/db?serverTimezone=" + TimeZone.getDefault().getID()


评论


最新的5.4.15版本也发生在我身上。但是,此问题已解决:在您的数据库旁边添加“?serverTimezone =“ + TimeZone.getDefault()。getID()”,即可解决此问题。

– Tes
5月14日下午3:11

#15 楼

将服务器时间设置为UTC不会产生影响(例如,使用jdbc:mysql://localhost:3306/myschema?serverTimezone=UTC时,即使您的应用程序/数据库服务器不在此时区中也是如此。重要的是应用程序连接字符串+数据库要与相同时区同步。

换句话说,只需在数据库服务器上将serverTimezone=UTC设置为不同的时区,就会移动从数据库中提取的所有日期

评论


这就是答案!谢谢!

–parsecer
12月1日的1:31

#16 楼

我正在使用mysql-connector-java-8.0.13并遇到相同的问题。
我在命令行控制台中创建了数据库,并通过在命令行上使用@Dimitry Rud的解决方案解决了此问题:

SET GLOBAL time_zone = '-6:00';


我不需要重新启动任何东西,设置时间,然后立即在eclipse中运行我的代码,它没有任何问题。

该错误应该在较旧的版本中已修复,但我认为我收到此错误是因为我在控制台中创建了数据库,但未设置。我没有使用工作台,也没有使用其他应用程序来管理控制台,而不是控制台。

#17 楼

这对我有用。

在DBeaver 6.0上:转到“连接设置”>“驱动程序属性”>“服务器时区”>“设置UTC”。

还必须在spring boot config中进行设置下面的属性。

jdbc:mysql:// localhost:/?serverTimezone = UTC

#18 楼

显然,要使MySQL JDBC驱动程序的5.1.33版与UTC时区一起使用,必须在连接字符串中显式指定serverTimezone。

spring.datasource.url = jdbc:mysql://localhost:3306/quartz_demo?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC


#19 楼

在mysql工作台上运行以下sql语句:


SET @@ global.time_zone ='+00:00';
SET @@ session.time_zone ='+00: 00';

使用以下sql语句检查是否设置了值:


评论


当有问题的错误在尝试从IntelliJ IDEA建立连接时弹出时,这对我有用。

– Faheem Hassan Zunjani
19年4月8日在15:40

#20 楼

当我尝试在Windows上使用spring boot项目时,我遇到了同样的问题。

数据源网址应为:

spring.datasource.url=jdbc:mysql://localhost/database?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC

#21 楼

在MySQL数据库中运行以下查询以解决错误

MariaDB [xxx> SET @@global.time_zone = '+00:00';
Query OK, 0 rows affected (0.062 sec)

MariaDB [xxx]> SET @@session.time_zone = '+00:00';
Query OK, 0 rows affected (0.000 sec)

MariaDB [xxx]> SELECT @@global.time_zone, @@session.time_zone;


#22 楼

我遇到了与您类似的错误,但是我的服务器时区值为'Afr。 centrale Ouest'
,所以我做了这些步骤:

MyError(在IntelliJ IDEA社区版上):

    InvalidConnectionAttributeException: The server time zone value 'Afr. centrale Ouest' 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 u....


我遇到了这个问题我将mysql服务器升级到SQL Server 8.0(MYSQL80)时出现的问题。

此问题的最简单解决方案是在MYSQL Workbench中编写以下命令-

  SET GLOBAL time_zone = '+1:00'


时区之后的值将等于GMT +/-时区中的差异。上面的示例适用于北非(GMT + 1:00)或印度(GMT + 5:30)。
将解决此问题。

在您的计算机中输入以下代码Mysql Workbench和执行查询

[问题/问题的源链接]

[答案的源链接]

[解决方案屏幕截图]

#23 楼

我已将以下行添加到我的/etc/mysql/my.cnf文件中:

default_time_zone='+00:00'


重新启动MySQL服务器:

systemctl restart mysql


而且它就像一种魅力。

#24 楼

Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/resultout? useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC","root",""))


这实际上是解决此问题的方法,但不仅是将其复制并粘贴到程序中。如果您只看一行,就会发现“结果”,这是我的数据库的名称,您必须编写您的数据库。

共有三个字符串部分,第一个是url,第二个是用户名,第三个是密码。在上一段中,我们清除了url。第二个和第三个String组件表示为您的用户名和密码,您必须相应地进行更改。

感谢

#25 楼

我在LibreOffice Base中也遇到了完全相同的问题。所以我只在连接字符串中指定了一个非“夏令时区”。

我尝试不带“&serverTimezone = MST”,但是也失败了。

我也尝试了“&serverTimezone = MDT”,但是失败了,所以由于某种原因,它不喜欢夏令时!!

#26 楼

就我而言,这是一个测试环境,我必须使现有的应用程序能够在不进行任何配置更改的情况下运行,并且如果可能的话,在不进行任何MySQL配置更改的情况下进行操作。
我可以按照@vinnyjames的建议和将服务器时区更改为UTC:

ln -sf /usr/share/zoneinfo/UTC /etc/localtime
service mysqld restart


这足以解决我的问题。

#27 楼

我无需更改任何代码即可解决此问题。只需转到系统时间设置并设置时区即可。在我的情况下,默认时区为UTC,我将其更改为本地时区。重新启动所有服务后,一切都对我有用。

#28 楼

我来晚了,但是,如果您正在努力解决以下错误并使用datasource(javax.sql.DataSource):

The server time zone value 'CEST' is unrecognized or represents more than one time zone.


设置以下行来消除该错误:

MysqlDataSource dataSource = new MysqlDataSource();
dataSource.setServerTimezone("UTC");


#29 楼

我遇到了同样的错误,在我的情况下,我将服务器端口号更改为3308,以前是3306。这将我的项目连接到MySQL数据库。

这里我们必须更改连接代码
Class.forName("com.mysql.cj.jdbc.Driver");
cn=(java.sql.Connection)DriverManager.getConnection("jdbc:mysql://localhost:3308/test2?zeroDateTimeBehavior=convertToNull","root","");

还需要在连接代码中更改端口号,因为localhost:3308可以解决该错误。
我的情况下也需要管理属性。


#30 楼

同意@bluecollarcoder的答案,但是最好在连接字符串的末尾使用TimeZone.getDefault().getID();

"jdbc:mysql://localhost/db?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=" + TimeZone.getDefault().getID();  


在这种情况下,Timezone参数会根据本地计算机时区自动更新。

评论


那是不对的。 useLegacyDatetimeCode = false的点是不必指定serverTimezone,因此客户端可以更正时区差异。

–antgar9
19年4月16日在12:13