繁体   English   中英

MySQL JDBC 驱动程序 5.1.33 - 时区问题

[英]MySQL JDBC Driver 5.1.33 - Time Zone Issue

一些背景:

我有一个在 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.

为什么会这样?

显然,要让 MySQL JDBC 驱动程序版本 5.1.33 与 UTC 时区一起工作,必须在连接字符串中明确指定serverTimezone

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

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

SET GLOBAL time_zone = '+3:00';

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

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

如果您使用的是 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块。

只需在 application.properties 上添加 serverTimeZone=UTC,它就对我有用。
spring.datasource.url=jdbc:mysql://localhost/db?serverTimezone=UTC

我解决了在 URL 中放置以下连接字符串

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

这是从 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:

TimeUtil.class.getResourceAsStream(TIME_ZONE_MAPPINGS_RESOURCE);

参数useLegacyDatetimeCode允许在使用日期时自动更正客户端和服务器时区之间的差异。 因此,它可以帮助您精确地不必在每个部分中指定时区。 虽然使用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 中。

  1. 我在[mysqld]部分的 mysql 配置文件中添加了

    default_time_zone='+03:00'
  2. 并重启mysql服务器:

     sudo service mysql restart

在哪里+03:00我的 UTC 时区。

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

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

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

我的 url jdbc 连接:

"jdbc:mysql://localhost/java"

上面的程序会产生那个时区错误。

在您的数据库名称之后,您必须添加: ?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

我有同样的问题,我解决了它只将“?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

我们需要解决serverTimezone问题的一切:

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

您可以在 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

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

换句话说,只需在数据库服务器上使用不同的时区设置serverTimezone=UTC就会改变从数据库中提取的任何日期

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

SET GLOBAL time_zone = '-6:00';

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

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

显然,要让 MySQL JDBC 驱动程序版本 5.1.33 与 UTC 时区一起工作,必须在连接字符串中明确指定 serverTimezone。

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

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

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

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

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

这对我有用。

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

此外,在 Spring Boot 配置中,必须设置以下属性。

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

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

这实际上是解决这个问题的方法,但不要只是将其复制并粘贴到您的程序中。 如果您只阅读该行,您会发现“resultout”,这是我的数据库的名称,您必须编写自己的。

字符串由三个部分组成,第一个是 url,第二个是用户名,第三个是密码。 在上面的段落中,我们清除了 url。 第二个和第三个字符串组件如您所说的您的用户名和密码,您必须相应地更改。

谢谢

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

数据源 url 应该是:

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

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

[问题/问题的源链接]

[答案的来源链接]

[解决方案截图]

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

default_time_zone='+00:00'

重新启动 MySQL 服务器:

systemctl restart mysql

它就像一个魅力。

application.properties文件中按位置为 Spring Boot 应用程序设置时区

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>

我在 LibreOffice Base 中也遇到了完全相同的问题。 所以我只是在连接字符串中指定了一个非“夏令时时区”。
**在此处输入图片描述**

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

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

在我的例子中,它是一个测试环境,我必须让一个现有的应用程序在没有任何配置更改的情况下工作,并且如果可能的话,不需要任何 MySQL 配置更改。 我能够通过遵循@vinnyjames 的建议并将服务器时区更改为 UTC来解决此问题:

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

这样做足以让我解决问题。

我在没有任何单一代码更改的情况下解决了这个问题。 只需转到系统时间设置并设置时区。 在我的情况下,默认时区是 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");

我遇到了同样的错误,在我的情况下,我将服务器端口号更改为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以解决错误。

此外,在我的情况下,管理属性。 在此处输入图像描述

连接字符串对我有用

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

我正在使用 Gradle 我的 build.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'
}

我的.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

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

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

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

我还在 NetBeans 中获得了相同的运行 java JDBC。 这就是它固定的方式

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

# Set timezone to Europe/Athens UTC+02:00 
SetEnv TZ Europe/Athens.

在 MySQL 的 conf 按钮中,我打开了 my.ini 文件,在最后一行我输入了“Europe/Athens”

停止并启动 Apache 和 MySQL

问题已解决。

*(本地机器时区不同,但没问题。)

只需在 application.properties 文件中使用以下代码修改连接字符串。


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

package pack1;

import java.sql.Connection;
import java.sql.DriverManager;
import javax.swing.JOptionPane;

public class sqliteConnection {
    Connection conn=null;

    public static Connection dbConnector() {
        try {Class.forName("com.mysql.jdbc.Driver");

        Connection conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306", "root", "");
        JOptionPane.showMessageDialog(null, "connection is succesful");
        return conn;

        } catch(Exception e) {
            JOptionPane.showMessageDialog(null, e);
            return null;

        ////you need also to execute this in database ===> SET GLOBAL time_zone = '+3:00';
        }
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM