MySQL JDBC驱动5.1.33 -时区问题

背景知识:

我有一个运行在Tomcat 7上的Java 1.6 web应用程序。数据库为MySQL 5.5。之前,我使用Mysql JDBC驱动程序5.1.23连接到DB。一切工作。我最近升级到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.

为什么会这样?

717966 次浏览

显然,要让5.1.33版本的MySQL JDBC驱动程序与UTC时区兼容,必须在连接字符串中显式指定serverTimezone

jdbc:mysql://localhost/db?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC
这是mysql-connector-java从5.1.33到5.1.37版本的一个错误。 我在这里报告了它:http://bugs.mysql.com/bug.php?id=79343

< p > <强>编辑: 这已经从mysql-connector-java 5.1.39

修正

这是在loadtimezonemapping方法中的TimeUtil类中出现的一个拼写错误,该方法会引发NPE定位/com/mysql/jdbc/TimeZoneMapping。属性文件。如果你看一下代码,文件应该位于TimeUtil类装入器中,而不是TimeZone:

TimeUtil.class.getResourceAsStream(TIME_ZONE_MAPPINGS_RESOURCE);

参数useLegacyDatetimeCode允许在使用日期时自动纠正客户端和服务器时区之间的差异。因此,它帮助您精确地不必在每个部分指定时区。虽然使用serverTimeZone参数是一种变通方法,并且在发布补丁的同时,您可以像我一样更好地尝试自己更正代码。

  • 如果它是一个独立的应用程序,您可以尝试简单地添加a 纠正com/mysql/jdbc/TimeUtil类到你的代码,要小心 与罐子装载顺序。这可以帮助: 李https://owenou.com/2010/07/20/patching-with-class-shadowing-and-maven.html < / p > < / > 如果它是一个web应用程序,更简单的解决方案是创建你自己的 Mysql-connector-java-5.1.37-patched.jar,直接替换。class

如果你正在使用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>

保存pom.xml文件后,Maven将自动重新构建项目。

连接字符串应该像这样设置:

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

如果你在xml文件(如persistence.xmlstandalone-full.xml等)中定义连接,你应该使用&amp;CDATA块而不是&

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

SET GLOBAL time_zone = '+3:00';

  1. 我在(mysqld)节中添加了mysql配置文件

    default_time_zone='+03:00'
    
  2. And restart mysql server:

    sudo service mysql restart
    

Where +03:00 my UTC time zone.

Path to config file on my os ubuntu 16.04:

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

警告:如果你所在的时区有夏季和冬季时间。如果要更改时间,必须在配置中更改utc。一年两次(通常)或用sudo设置crontab。

我的url jdbc连接

"jdbc:mysql://localhost/java"

我没有修改任何代码就解决了这个问题。只需进入系统时间设置和设置时区。在我的情况下,默认时区是UTC,我将其更改为我的本地时区。重启所有服务后,一切都恢复正常了。

我解决了把下面的连接字符串在URL

jdbc:mysql://localhost:3306/db?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC
我在LibreOffice基地也遇到了完全相同的问题。所以我只是在连接字符串中指定了一个非“夏时制时区” **enter image description here** < / p >

我尝试了没有“&serverTimezone=MST”,但也失败了。

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

我也有同样的问题,我解决了它只附加”?serverTimezone=UTC"到我的字符串连接。

我的问题是:

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

同意@bluecollarcoder的回答,但最好在连接字符串的末尾使用< em > TimeZone.getDefault().getID(); < / em >:

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

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

我正在使用mysql-connector-java-8.0.13,有同样的问题。 我在命令行控制台创建了我的数据库,并通过在命令行上使用@Dimitry路德的解决方案解决了这个问题:

SET GLOBAL time_zone = '-6:00';

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

这个错误应该在旧版本中得到修复,但我想我得到了这个错误,因为我在控制台中创建数据库后,我没有设置这个。我没有使用工作台或其他应用程序来管理这个,而不是控制台。

在阅读了几篇关于这个主题的文章后,测试了不同的配置,并基于这个mysql bug线程的一些见解,这是我的理解:

  • 服务器时区非常重要,特别是在将数据库中存储的日期转换为应用服务器的时区时。还有其他影响,但这是最明显的影响
  • GMT x UTC时区系统。格林尼治时间是在19世纪后期被构想出来的,可以在标准时间和夏季时间之间转换。这个属性可能会导致数据库服务器切换到夏季时间,而应用程序没有注意到它(可能还有其他复杂情况,但我没有进一步研究)。UTC不随时间变化(在经度0°处,它总是在平均太阳时间的1秒内)。
  • serverTimeZone定义是在mysql jdbc连接器5.1版本之前引入的。在版本8之前,使用useLegacyDatetimeCode=true可以忽略它,它与useJDBCCompliantTimezoneShift=true一起将使应用程序在每个连接上获得数据库时区。在此模式下,GMT时区(如“英国夏令时”)将转换为内部java/JDBC格式。新的时区可以在.properties文件中定义,比如这一个
  • 从jdbc驱动程序版本8开始,自动时间匹配(useJDBCCompliantTimezoneShift)和遗留时间格式(useLegacyDatetimeCode)被删除(参见mysql JDBC连接器变更日志)。因此,设置这两个参数没有效果,因为它们完全被忽略(新的默认值是useLegacyDateTimeCode=false)
  • 通过这种方式,如果任何时区(应用程序/数据库服务器)不是'UTC+xx'或'GMT+xx'格式,则将serverTimezone设置为强制性的
  • 将服务器时间设置为UTC没有任何影响(例如使用jdbc:mysql://localhost:3306/myschema?serverTimezone=UTC,即使您的应用程序/数据库服务器不在这个时区。重要的是应用程序连接字符串+数据库要与相同的时区同步。换句话说,只要在数据库服务器上使用不同的时区设置serverTimezone=UTC,就会转移从数据库中提取的任何日期
  • MySQL的默认时区可以通过my.ini或my.cnf文件(分别是windows / linux)设置为UTC+0,通过添加default-time-zone='+00:00'(详细信息在这个StackOverflow帖子中)
  • 在AWS (amazon web服务)上配置的数据库将自动分配UTC+0默认时间(请参阅AWS帮助页面)

我们需要用serverTimezone来修复问题的所有东西:

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

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

  1. 设置@@global。Time_zone = '+00:00';
  2. 设置@@session。Time_zone = '+00:00';

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

选择@@global。time_zone @@session.time_zone;

你可以在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
它为我工作了,只需在application.properties上添加serverTimeZone=UTC spring.datasource.url=jdbc:mysql://localhost/db?serverTimezone=UTC < / p >

这对我很管用。

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

另外,在春季启动配置中,必须设置下面的属性。

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

我迟到了,但如果你正在努力克服以下错误并使用数据源(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");
在我的例子中,这是一个测试环境,我必须使一个现有的应用程序在没有任何配置更改的情况下工作,如果可能的话,没有任何MySQL配置更改。 我能够通过遵循@vinnyjames的建议和更改服务器时区为UTC来修复这个问题:

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

这样做对我来说已经足够解决问题了。

我也得到了相同的运行java JDBC在NetBeans。这就是它如何修复的

我使用Xampp。在Apache的conf按钮中,我打开httpd.conf文件,并在第一行输入

# Set timezone to Europe/Athens UTC+02:00
SetEnv TZ Europe/Athens.
在MySQL的conf按钮中,我打开了我的.ini文件,在最后一行我键入 “欧洲/雅典”< / p >

停止并启动Apache和MySQL

固定的问题。

*(当地机器时区不同,但没有问题)

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

数据源url应该是:

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

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

在你的数据库名称之后,你必须添加这个:?useTimezone=true&serverTimezone=UTC。一旦你完成了这些,你的代码就可以正常工作了。

祝你好运。

我在数据库端执行了以下命令。

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社区服务器- GPL

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

运行下面的查询到mysql DB来解决这个错误

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;

我得到的错误类似于你的,但我的服务器时区值是'Afr。舟状骨的西部省 所以我做了这些步骤:

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中输入以下代码并执行查询

[问题/问题的来源链接]

[答案来源链接]

[解决方案截图] .

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

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

我在/etc/mysql/my.cnf文件中添加了以下一行:

default_time_zone='+00:00'

重启MySQL服务器:

systemctl restart mysql

它就像一个魔法。

只需在应用程序中使用以下代码修改连接字符串。属性文件。


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


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

这实际上是这个问题的解决方案,但不要只是复制粘贴到您的程序中。如果你只看这一行,你会发现'resultout',这是我的数据库的名称,你必须写下你的。

有三个字符串组件,第一个是url,第二个是用户名,第三个是密码。在上述段落中,我们清除了,url。第二个和第三个字符串组件,你的用户名和密码,你必须相应地改变。

谢谢

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

换句话说,简单地在数据库服务器上用不同的时区设置serverTimezone=UTC将转移从数据库中提取的任何日期

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

enter image description here

这里我们还必须更改连接代码。

Class.forName("com.mysql.cj.jdbc.Driver");
cn=(java.sql.Connection)DriverManager.getConnection("jdbc:mysql://localhost:3308/test2?zeroDateTimeBehavior=convertToNull","root","");

改变连接代码中的端口号也是必要的,因为localhost:3308可以解决错误。

同样,在我的例子中,admin属性。 enter image description here < / p >

根据位置为application.properties文件中的spring引导应用程序设置时区

spring.datasource.url=jdbc:mysql://localhost:3306/db?serverTimezone=Europe/Berlin

解决了CET / CEST时区的问题。pom.xml使用maven工件

    <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.22</version>
</dependency>

连接字符串为我工作这个

jdbc:mysql://localhost/<yourDbName>?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC

我使用Gradle我的构建。Gradle文件是这样的

dependencies {
// https://mvnrepository.com/artifact/mysql/mysql-connector-java
implementation group: 'mysql', name: 'mysql-connector-java', version: '8.0.17'
testCompile group: 'junit', name: 'junit', version: '4.12'
}

my.ini

最后加上这一行:

default-time-zone = '+05:30'

从终端运行此命令

>> sudo mysql -e "SET GLOBAL time_zone = ‘+5:30’;" -u root
>> sudo mysql -e "SELECT @@global.time_zone;" -u root

如果两者都不工作,请尝试使用终端从sqoop使用此请求

>> sqoop list-databases --connect "jdbc:mysql://localhost/employees?serverTimezone=UTC" --username sqoop -P

或者你可以用这个替换你的请求URL

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