Драйвер JDBC MySQL 5.1.33 - проблема с часовым поясом


361

Немного предыстории:

У меня есть веб-приложение Java 1.6, работающее на Tomcat 7. База данных 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.

Почему это происходит?


1
Как выглядит ваш JDBC URL?
Дэвид Левеск

Проверьте мой ответ stackoverflow.com/a/44720416/4592448 . Я думаю, что его лучший ответ)
Fortran

Ответы:


676

Очевидно, чтобы заставить версию 5.1.33 драйвера JDBC MySQL работать с часовым поясом UTC, необходимо serverTimezoneявно указать в строке соединения.

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

4
Согласно документам useJDBCCompliantTimezoneShift не имеет никакого эффекта при использовании useLegacyDatetimeCode = false. Поэтому там не нужно ...
Матоф

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>
августа

5
Это не правильно. Точка useLegacyDatetimeCode = false не обязывает указывать serverTimezone, поэтому клиент исправляет различия часовых поясов. Это ошибка в той версии клиента MySQL.
antgar9

2
Это решение разрушает часовой пояс за исключением GMT. Я думаю, что правильное решение недооценено одно ниже
DuncanSungWKim

1
Решение работает с 8.0.17. Произошло со свежей установкой MySQL. Не могу поверить, что эта ошибка не была исправлена ​​после стольких лет.
Тилман

102

Я решил эту проблему, настроив MySQL.

SET GLOBAL time_zone = '+3:00';


6
если вы используете ММС часовой пояс это +3, то вы можете использовать folowing в качестве адреса БД: jdbc:mysql://localhost/db?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=Europe/Moscow. Похоже, MySQL-разъем не понимает короткие имена часовых поясов.
17

2
Что вы делаете, когда летнее время меняет часы?
Исапир

3
В mysql 8.0 вы можете вызвать "set persist time_zone = '+00: 00';" чтобы установить его в UTC постоянно, без необходимости редактировать my.cnf или перезапускать сервер. См. Mysqlserverteam.com/…
ccleve

Если вы устанавливаете это с помощью уникального ручного SQL-запроса, этот параметр вернется к исходному значению после перезапуска БД.
CBA110

работает - не забудьте изменить строку местного часового пояса вместо +3 SET GLOBAL time_zone = '+3: 00';
Правин

61

Прочитав несколько постов на эту тему, протестировав различные конфигурации и основываясь на некоторых выводах из этой ветки ошибок MySQL , я понял следующее:

  • часовой пояс сервера важен, в частности, для преобразования дат, хранящихся в базе данных, в часовой пояс сервера приложений. Есть и другие последствия, но это самое заметное
  • GMT x UTC системы часовых поясов. GMT был задуман в конце 19-го века и может быть переключен между стандартным и летним временем. это свойство может привести к ситуации, когда сервер базы данных перейдет на летнее время, а приложение не заметит этого (возможно, есть другие сложности, но я не стал исследовать дальше). UTC не изменяется во времени (оно всегда находится в пределах около 1 секунды от среднего солнечного времени на 0 ° долготы).
  • Определение serverTimeZone было введено в коннекторах mysql jdbc версии 5.1. до версии 8 его можно было игнорировать useLegacyDatetimeCode=true, что в сочетании с этим useJDBCCompliantTimezoneShift=trueзаставляло бы приложение получать часовой пояс базы данных при каждом соединении. В этом режиме часовые пояса GMT, такие как «Британское летнее время», будут преобразованы во внутренний формат Java / JDBC. Новые часовые пояса могут быть определены в файле .properties, таком как этот
  • Начиная с версии 8 драйвера jdbc, автоматическое сопоставление времени ( useJDBCCompliantTimezoneShift) и устаревший формат времени ( useLegacyDatetimeCode) были удалены ( см. Список изменений в соединителе jdbc для mysql ). поэтому установка этих двух параметров не имеет никакого эффекта, поскольку они полностью игнорируются (новое значение по умолчанию - useLegacyDateTimeCode=false)
  • Таким образом, настройка serverTimezoneстала обязательной, если какой-либо из часовых поясов (серверы приложений / баз данных) не в формате «UTC + xx» или «GMT + xx»
  • Установка времени сервера как UTC не влияет (например jdbc:mysql://localhost:3306/myschema?serverTimezone=UTC, даже если ваши серверы приложений / баз данных не находятся в этом часовом поясе. Важно, чтобы строка подключения приложения + база данных были синхронизированы с одним и тем же часовым поясом. Другими словами , просто установив serverTimezone = UTC с другим часовым поясом на сервере базы данных сместятся любые даты , извлеченных из базы данных
  • Часовой пояс MySQL по умолчанию можно установить в UTC + 0 с файлами my.ini или my.cnf (соответственно windows / linux), добавив строку default-time-zone='+00:00'(подробности в этом сообщении StackOverflow )
  • Для баз данных, настроенных в AWS (веб-сервисы Amazon), автоматически назначается время UTC + 0 по умолчанию ( см. Страницу справки AWS здесь )

1
Хороший ответ, спасибо. Различные пули все полезны. Я пошел с предложением положить default-time-zone = '+00:00'в доморощенный /usr/local/etc/my.cnfфайл. Кажется, что пробелы вокруг =важны, поэтому вы можете отредактировать этот маркер, чтобы включить их.
Марк Эдингтон

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>

Maven автоматически перестроит ваш проект после сохранения pom.xmlфайла.


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
Роберт Нестрой

13
8.0.13 выдает такую ​​же ошибку. 5.1.47 у меня работает однако.
localhost

36

Строка подключения должна быть установлена ​​следующим образом:

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

Если вы определяете соединение в xmlфайле (например persistence.xml, standalone-full.xmlи т. Д.), Вместо этого &вы должны использовать &amp;или использовать CDATAблок.


1
Это не правильно. Точка useLegacyDatetimeCode = false не обязывает указывать serverTimezone, поэтому клиент исправляет различия часовых поясов.
antgar9

Это работало для меня, соединяясь с MySQL 5.7 с phpStorm 2019.1.4.
moult86

29

Это ошибка в mysql-connector-java с версии 5.1.33 до 5.1.37. Я сообщил об этом здесь: http://bugs.mysql.com/bug.php?id=79343

Отредактировано: это было исправлено в mysql-connector-java 5.1.39

Это была опечатка в классе TimeUtil в методе loadTimeZoneMappings, которая вызвала 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

  • Если это веб-приложение, более простое решение - создать собственный mysql-connector-java-5.1.37-patched.jar, подставив .class непосредственно в исходный jar.


Милый, спасибо за сообщение об этом. Рад, что кто-то смог зафиксировать ошибку. Вы знаете, когда будет выпущено исправление?
bluecollarcoder

Решение, которое вы предлагаете, великолепно, но я думаю, что изменение источника драйвера и управление зависимостями Maven, вероятно, слишком раздражает для большинства людей.
bluecollarcoder

4
@Gili Это не исправлено в версии 6.0.6
Imme22009

6
Ошибка по-прежнему присутствует в 8.0.11
Джон Литтл

3
@JohnLittle У меня тоже есть эта проблема в 8.0.15, но она больше не вызвана ошибкой. Часовые пояса загружены правильно, но CET и CEST (эти часовые пояса вызывают у меня проблемы) не включены ни в, TimeZone.getAvailableIDs()ни в, TimeZoneMapping.propertiesтак что это решение здесь не поможет. Решение будет probaby быть установка , как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

Это сработало для меня, просто добавив serverTimeZone = UTC в application.properties.
spring.datasource.url=jdbc:mysql://localhost/db?serverTimezone=UTC


22
  1. Я добавил в конфигурационный файл mysql в разделе [mysqld]

    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 В КОНФИГ. ЕСЛИ ВРЕМЯ ИЗМЕНЕНИЯ. ДВАЖДЫ В ГОД (ОБЫЧНО) ИЛИ УСТАНАВЛИВАЙТЕ CRONTAB С SUDO.

Мой URL JDBC соединение:

"jdbc:mysql://localhost/java"

1
Необходимость перезапуска Mysql практически не запускается практически во всех случаях производственного использования. Это становится еще большей проблемой, когда репликации участвуют.
bluecollarcoder

@bluecollarcoder Требуется добавить только в разделе [mysqld]. Или добавьте раздел [mysqld], если у него нет раздела. Пример моего конфига pastebin.com/j4F7t2KS
Fortran

1
Я обновил / etc / localtime моего Linux-сервера с / usr / share / zoneinfo / US / Pacific до / usr / share / zoneinfo / America / Los_Angeles, затем перезапустил службу mysql, и это исправило проблему для меня.
vinnyjames

В моем случае для предоставленного синтаксиса произошла ошибка при перезапуске, и правильный синтаксис был: default-time-zone='+03:00'вместо этого, согласно этому ответу . Также идет от DBeaver.
wscourge

это неуместно, если вы должны сказать всем разработчикам в вашей компании изменить их конфигурацию MySQL :)
pheromix

16

У меня та же проблема, и я решил ее добавить только «? 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 

14

Приведенная выше программа сгенерирует эту ошибку часового пояса.

После того, как ваше имя базы данных нужно добавить следующее: ?useTimezone=true&serverTimezone=UTC. После того как вы сделали ваш код будет работать нормально.

Удачи :)


14

Я выполнил следующее на моей стороне базы данных.

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

Все, что нам нужно, чтобы решить проблему с serverTimezone:

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

Это случилось со мной и с последней версией 5.4.15. Но исправлено это: добавление "? ServerTimezone =" + TimeZone.getDefault (). GetID () "прямо рядом с вашей базой данных, решает проблемы.
Тест

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';

Мне не нужно было ничего перезапускать, устанавливать время и немедленно запускать мой код в затмении, это без проблем.

Ошибка должна быть исправлена ​​в более старой версии, но я думаю, что я получил эту ошибку, потому что после того, как я создал базу данных в консоли, я не установил ее. Я не использую верстак или другое приложение для управления этим, а не консоль.


6

Из mysql workbench запустите следующие операторы 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.
Фахим Хасан Зунджани

6

Это сработало для меня.

на DBeaver 6.0: выберите «Параметры подключения»> «Свойства драйвера»> «Часовой пояс сервера»> «Установить UTC».

Также, в весеннем загрузочном конфиге, пришлось установить свойство ниже.

JDBC: MySQL: // локальный: / serverTimezone = UTC


5

По-видимому, чтобы заставить версию 5.1.33 драйвера JDBC MySQL работать с часовым поясом 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.

URL источника данных должен быть:

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


3

Запустите приведенный ниже запрос к базе данных 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;

3

Я получил ошибку, похожую на вашу, но мой Значение часового пояса сервера 'Afr. Centrale Ouest ', поэтому я сделал эти шаги:

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 Workbench -

  SET GLOBAL time_zone = '+1:00'

Значение после часового пояса будет равно GMT +/- Разница в вашем часовом поясе. Приведенный выше пример для Северной Африки (GMT + 1: 00) / или для Индии (GMT + 5: 30). Это решит проблему.

Введите следующий код в Mysql Workbench и выполните задание

[исходная ссылка на вопрос / проблему]

[ссылка на источник для ответа]

[Решение ScreenShot]


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

На самом деле это решение этой проблемы, но не просто скопируйте и вставьте ее в свою программу. Если вы просто прочитаете строку, вы найдете «resultout», это имя моей базы данных, и вы должны написать свою.

Существует три строковых компонента: первый - это URL, второй - имя пользователя, а третий - пароль. В вышеприведенном абзаце мы очистили, URL. Второй и третий строковые компоненты, как указано ваше имя пользователя и пароль, вы должны изменить соответствующим образом.

Спасибо


1

Я решил эту проблему без единого изменения кода. просто зайдите в настройку системного времени и установите часовой пояс. В моем случае часовой пояс по умолчанию был UTC, который я изменил на свой местный часовой пояс. После перезапуска всех служб у меня все заработало.


1

Я опаздываю, но если вы боретесь со следующей ошибкой и используете источник данных (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

И это работает как шарм.


1

Установка времени сервера как UTC не влияет (например jdbc:mysql://localhost:3306/myschema?serverTimezone=UTC, даже если ваши серверы приложений / баз данных не находятся в этом часовом поясе. Важно, чтобы строка подключения приложения + база данных были синхронизированы с одним и тем же часовым поясом.

Другими словами, простая установка serverTimezone=UTCдругого часового пояса на сервере базы данных сместит любые даты, извлеченные из базы данных.


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
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.