MySQL JDBCドライバー5.1.33-タイムゾーンの問題


360

背景:

Tomcat 7でJava 1.6 webappを実行しています。データベースは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.

なんでこんなことが起こっているの?


1
JDBC URLはどのように見えますか?
David Levesque 2014年

私の回答stackoverflow.com/a/44720416/4592448を確認してください。私はその最良の答えだと思います)
Fortran

回答:


674

どうやら、MySQL JDBCドライバーのバージョン5.1.33をUTCタイムゾーンで動作させるserverTimezoneには、接続文字列で明示的に指定する必要があります。

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

4
ドキュメントによると、useLegacyDatetimeCode = falseを使用する場合、useJDBCCompliantTimezoneShiftは効果がありません。したがって、ここでは必要ありません...
matof '27

24
これは私のエラーを解決します。追加の注意、&amp;で&をエスケープします。persistence.xmlファイル内:<property name = "javax.persistence.jdbc.url" value = "jdbc:mysql:// localhost / test?useUnicode = true&amp; useJDBCCompliantTimezoneShift = true&amp; useLegacyDatetimeCode = false&amp; serverTimezone = UTC" />
pdem

5
不正解です。useLegacyDatetimeCode = falseのポイントはserverTimezoneを指定する必要がないため、クライアントはタイムゾーンの差異を修正します。これは、そのバージョンのMySQLクライアントのバグです。
antgar9

2
このソリューションは、GMT以外のタイムゾーンを台無しにします。適切な解決策は、1つ下で
DuncanSungWKim 2017

1
ソリューションは8.0.17で動作します。新しいMySQLインストールで発生しました。このバグが何年も経っても修正されていないことは信じられません。
Tilman Hausherr

101

MySQLを構成することでこの問題を解決しました。

SET GLOBAL time_zone = '+3:00';


6
+3のMSKタイムゾーンを使用している場合は、次のようにDBアドレスとして使用できますjdbc:mysql://localhost/db?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=Europe/Moscow。mysql-connectorが短いタイムゾーン名を理解できないようです。
2017

2
夏時間により時計が変更された場合はどうしますか?
isapir 2018年

3
mysql 8.0では、「set persist time_zone = '+00:00';」を呼び出すことができます。my.cnfを編集したりサーバーを再起動したりすることなく、永続的にUTCに設定します。mysqlserverteam.com/…を
ccleve

一意の手動SQLクエリを介してこれを設定している場合、この設定はDBの再起動後に元の値に戻ります。
CBA110

機能します-+3 SET GLOBAL time_zone = '+3:00'の代わりにローカルのタイムゾーン文字列を変更することを忘れないでください。
Pravin

61

このトピックに関するいくつかの投稿を読んだ後、さまざまな構成をテストし、私が理解しているこのmysqlバグスレッドからのいくつかの洞察に基づいています。

  • サーバーのタイムゾーンは、データベースに保存されている日付をアプリケーションサーバーのタイムゾーンに変換するために特に重要です。他の影響もありますが、これは最も顕著なものです
  • 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のデフォルトのタイムゾーンは、my.iniまたはmy.cnfファイル(それぞれWindows / Linux)でUTC + 0に設定できます(次のStackOverflow投稿のdefault-time-zone='+00:00'詳細)。
  • AWS(amazon Webサービス)で構成されたデータベースには、UTC + 0のデフォルト時間が自動的に割り当てられます(AWSヘルプページはこちらをご覧ください

1
いい答え、ありがとう。さまざまな箇条書きはすべて便利です。私はdefault-time-zone = '+00:00'自作の/usr/local/etc/my.cnfファイルにaを入れるという提案を行いました。周りのスペース=は重要なようですが、弾丸を編集してそれらを含めることができます。
Mark Edington、

51

Mavenを使用している場合は、別のMySQLコネクタバージョンを設定できます(同じエラーが発生したため、6.0.2から5.1.39に変更しました)pom.xml

<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が自動的にプロジェクトを再ビルドします。


2
mysql-connector-java / 6-> mysql-connector-java / 5.1.20をダウンロードするだけで動作します。ありがとう!
結合

6
ダウングレードは避けてください。また、それは6.0.6まだ修正されていません。上記のソリューションを使用する方がよい
phil294

最新のjarでも同じエラーが発生する[mysql-connector-java-6.0.5.jar:6.0.5]
user2478236

18
私は8.0.12でもこれを持っています
Robert Niestroj

13
8.0.13でも同じエラーが発生します。5.1.47は私のために動作します。
localhost

36

接続文字列は次のように設定する必要があります。

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

あなたが接続を定義している場合はxml、ファイルを(のようなpersistence.xmlstandalone-full.xmlなど。)、代わりに&あなたが使うべき&amp;か、使用CDATAブロックを。


1
不正解です。useLegacyDatetimeCode = falseのポイントはserverTimezoneを指定する必要がないため、クライアントはタイムゾーンの差異を修正します。
antgar9

これは、phpStorm 2019.1.4を使用してMySQL 5.7に接続するのに役立ちました。
moult86

29

これは、バージョン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ファイルを見つけるのを引き起こしました。コードを見ると、ファイルはTimeZoneではなくTimeUtilクラスローダー内にあるはずです。

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に置き換えることです。


これを報告してくれてありがとう。誰かがバグを突き止めることができてうれしい。修正がいつリリースされるか知っていますか?
bluecollarcoder

あなたが提案している解決策は素晴らしいですが、ドライバーのソースを変更してMavenの依存関係を管理することは、おそらくほとんどの人にとって煩わしすぎます。
bluecollarcoder 2016

4
@Giliこれはリリース6.0.6の時点では修正されていません
Imme22009 2017

6
バグはまだ8.0.11に存在しています
John Little

3
@JohnLittle 8.0.15にもこの問題がありますが、バグが原因ではなくなりました。でどちらのタイムゾーンが正しくロードされますが、CET及びCEST(私にはトラブルの原因これらのタイムゾーン)が含まれていないTimeZone.getAvailableIDs()もでTimeZoneMapping.properties、このソリューションはここに助けにはなりませんので。解決策は次のように設定されますserverTimezone=Europe/Berlin
JPT

29

以下の接続文字列をURLに入れることを解決しました

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

1
不正解です。useLegacyDatetimeCode = falseのポイントはserverTimezoneを指定する必要がないため、クライアントはタイムゾーンの差異を修正します。
antgar9

25

application.propertiesにserverTimeZone = UTCを追加するだけで機能しました。
spring.datasource.url=jdbc:mysql://localhost/db?serverTimezone=UTC


22
  1. セクション[mysqld]の mysql設定ファイルに追加しました

    default_time_zone='+03:00'
  2. mysqlサーバーを再起動します。

    sudo service mysql restart

どこで+03:00私のUTCタイムゾーン。

私のos ubuntu 16.04の設定ファイルへのパス:

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

警告:タイムゾーンに夏と冬の時間がある場合。時間を変更する場合は、構成のUTCを変更する必要があります。年に2回(通常)、またはSUDOでCRONTABを設定します。

私のURL jdbc接続:

"jdbc:mysql://localhost/java"

1
Mysqlを再起動しなければならないということは、基本的に、ほとんどすべての本番環境のユースケースでは重要ではありません。レプリケーションが関係する場合は、さらに問題になります。
bluecollarcoder

@bluecollarcoder [mysqld]セクションでのみ追加が必要です。または、セクションがない場合は[mysqld]セクションを追加します。私の設定の例pastebin.com/j4F7t2KS
Fortran

1
Linuxサーバーの/ etc / localtimeを/ usr / share / zoneinfo / US / Pacificから/ usr / share / zoneinfo / America / Los_Angelesに更新してから、mysqlサービスを再起動すると、問題が解決しました。
vinnyjames

提供構文については、私の場合は、再起動時にエラーがあった、と正しい構文は:default-time-zone='+03:00'代わりに、この回答のとおり。またDBeaverから来ています。
wscourge 2019

社内のすべての開発者にMySQL設定を変更するように指示する必要がある場合は適切ではありません:)
pheromix

16

私は同じ問題を抱えており、文字列接続に「?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 

14

上記のプログラムは、そのタイムゾーンエラーを生成します。

データベース名の後にこれを追加する必要があります:?useTimezone=true&serverTimezone=UTC。コードを実行すると、問題なく機能します。

幸運を祈ります:)



13

問題を修正するために必要なすべてserverTimezone

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

これは、最新の5.4.15バージョンでも発生しました。追加"serverTimezone =?" +はTimeZone.getDefault()のgetId()URデータベースへの」右隣、問題を解決します。しかし、これで固定
TES

10

MySQLコネクタをMaven依存関係で使用できます。

<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

9

私はmysql-connector-java-8.0.13を使用していますが、同じ問題がありました。コマンドラインコンソールでデータベースを作成し、コマンドラインで@Dimitry Rudのソリューションを使用してこの問題を解決しました。

SET GLOBAL time_zone = '-6:00';

私は何も再起動する必要はなく、時間を設定してすぐにコードをeclipseで実行しましたが、問題なく接続されました。

バグは古いバージョンで修正される予定ですが、コンソールでデータベースを作成した後、これを設定しなかったため、このエラーが発生したと思います。コンソールではなく、ワークベンチや別のアプリを使用してこれを管理していません。


6

mysqlワークベンチから、次のSQLステートメントを実行します。

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

次のSQLステートメントを使用して、値が設定されているかどうかを確認します。

SELECT @@ global.time_zone、@@ session.time_zone;


2
IntelliJ IDEAから接続しようとしているときに問題のエラーがポップアップしたとき、これは私にとってはうまくいきました。
Faheem Hassan Zunjani

6

これでうまくいきました。

DBeaver 6.0の場合:[接続設定]> [ドライバーのプロパティ]> [サーバーのタイムゾーン]> [UTCの設定]に移動します。

また、春のブート設定では、以下のプロパティを設定する必要がありました。

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


5

どうやら、MySQL JDBCドライバーのバージョン5.1.33をUTCタイムゾーンで動作させるには、接続文字列でserverTimezoneを明示的に指定する必要があります。

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

3

LibreOffice Baseでもまったく同じ問題が発生していました。したがって、接続文字列で「夏時間以外のタイムゾーン」を指定しただけです。
**ここに画像の説明を入力してください**

「&serverTimezone = MST」なしで試しましたが、それも失敗しました。

「&serverTimezone = MDT」も試してみましたが、失敗したため、何らかの理由で夏時間は好きではありません!


3

WindowsでSpring Bootプロジェクトを操作しようとすると、同じ問題が発生しました。

データソースのURLは次のとおりです:

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


3

以下のクエリを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;

3

私はあなたのエラーに似ていますが、サーバーのタイムゾーンの値は 'Afrです。中央ウエスト 'だから私はこれらの手順を実行しました:

MyError(IntelliJ IDEA Community Edition):

    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ワークベンチで以下のコマンドを記述するだけです-

  SET GLOBAL time_zone = '+1:00'

タイムゾーンの後の値は、GMT +/-タイムゾーンの差と等しくなります。上記の例は、北アフリカ(GMT + 1:00)またはインド(GMT + 5:30)の場合です。それは問題を解決します。

Mysql Workbenchに次のコードを入力し、クエリを実行します

[質問/問題のソースリンク]

[回答のソースリンク]

[ソリューションスクリーンショット]


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

これは実際にはこの問題の解決策ですが、プログラムにコピーして貼り付けるだけではありません。この行を読むだけで 'resultout'が見つかります。これは私のデータベースの名前であり、自分で書く必要があります。

文字列コンポーネントは3つあり、1つ目はURL、2つ目はユーザー名、3つ目はパスワードです。上記の段落では、urlをクリアしました。2番目と3番目の文字列コンポーネントは、ユーザー名とパスワードを変更する必要があると言っています。

ありがとう


1

この問題は、コードを1つ変更することなく解決しました。システム時刻設定に移動して、タイムゾーンを設定するだけです。私の場合、デフォルトのタイムゾーンはUTCで、ローカルタイムゾーンに変更しました。すべてのサービスを再起動した後、すべてがうまくいきました。


1

私は遅れていますが、次のエラーに苦労して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");

1

私の場合、それはテスト環境であり、既存のアプリケーションを構成変更なしで、また可能であればMySQL構成変更なしで機能させる必要がありました。@vinnyjamesの提案に従い、サーバーのタイムゾーンをUTCに変更することで問題を解決できました。

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

それをすることは私が問題を解決するのに十分でした。


1

次の行を/etc/mysql/my.cnfファイルに追加しました。

default_time_zone='+00:00'

MySQLサーバーを再起動しました:

systemctl restart mysql

そしてそれは魅力のように働きます。


0

@bluecollarcoderの回答に同意しますTimeZone.getDefault().getID();が、接続文字列の最後で使用することをお勧めします。

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

この場合、Timezoneパラメータはローカルマシンのタイムゾーンに応じて自動的に更新されます。


不正解です。useLegacyDatetimeCode = falseのポイントはserverTimezoneを指定する必要がないため、クライアントはタイムゾーンの差異を修正します。
antgar9

0

application.propertiesファイルの次のコードで接続文字列を変更するだけです。


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

0

サーバー時間をUTCとして設定することによる影響はありません(たとえばjdbc:mysql://localhost:3306/myschema?serverTimezone=UTC、アプリケーション/データベースサーバーがこのタイムゾーンにない場合でも、を使用します。重要なのは、アプリケーション接続文字列+データベースを同じタイムゾーンと同期させることです。

つまり、serverTimezone=UTCデータベースサーバーで別のタイムゾーンを設定するだけで、データベースから抽出された日付がシフトされます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.