Драйвер JDBC MySQL 5.1.33 - проблема с часовым поясом
Немного предыстории:
У меня есть веб-приложение 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.
Почему это происходит?
37 ответов
Очевидно, чтобы заставить версию 5.1.33 драйвера JDBC MySQL работать с часовым поясом UTC, необходимо указать serverTimezone
явно в строке подключения.
jdbc:mysql://localhost/db?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC
Я решил эту проблему, настроив MySQL.
SET GLOBAL time_zone = '+3:00';
Прочитав несколько постов на эту тему, протестировав различные конфигурации и основываясь на некоторых выводах из этой ветки ошибок MySQL, я понял следующее:
- часовой пояс сервера важен, в частности, для преобразования дат, хранящихся в базе данных, в часовой пояс сервера приложений. Есть и другие последствия, но это самое заметное
- GMT x UTC системы часовых поясов. GMT был задуман в конце 19-го века и может быть переключен между стандартным и летним временем. это свойство может привести к ситуации, когда сервер базы данных перейдет на летнее время, а приложение не заметит этого (возможно, есть другие сложности, но я не стал исследовать дальше). UTC (по времени Португалии, а не по Гринвичу по Гринвичу) не изменяется во времени, поэтому является более стабильным
- Определение serverTimeZone было введено в коннекторах mysql jdbc версии 5.1. до версии 8 его можно игнорировать с помощью
useLegacyDatetimeCode=true
, что в сочетании сuseJDBCCompliantTimezoneShift=true
заставит приложение получать часовой пояс базы данных при каждом подключении. В этом режиме часовые пояса GMT, такие как "Британское летнее время", будут преобразованы во внутренний формат Java/JDBC. Новые часовые пояса могут быть определены в файле.properties, таком как этот - Начиная с версии 8 драйвера jdbc, автоматическое сопоставление времени (
useJDBCCompliantTimezoneShift
) и устаревший формат времени (useLegacyDatetimeCode
) были удалены ( см. список изменений соединителя mysql jdbc). поэтому установка этих двух параметров не имеет никакого эффекта, так как они полностью игнорируются (новое значение по умолчанию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'
(подробности в этом сообщении Stackru) - Для баз данных, настроенных в AWS (веб-сервисы Amazon), автоматически назначается время UTC+0 по умолчанию ( см. Страницу справки AWS здесь)
Если вы используете 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
файл.
Строка подключения должна быть установлена следующим образом:
jdbc:mysql://localhost/db?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC
Если вы определяете соединение в xml
файл (такой как persistence.xml
, standalone-full.xml
и т. д.) вместо &
ты должен использовать &
или использовать CDATA
блок.
Это сработало для меня, просто добавив serverTimeZone=UTC в application.properties.spring.datasource.url=jdbc:mysql://localhost/db?serverTimezone=UTC
Я решил положить ниже строку подключения в URL
jdbc:mysql://localhost:3306/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
Отредактировано: это было исправлено из 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.
Я добавил в конфигурационный файл mysql в разделе [mysqld]
default_time_zone='+03:00'
И перезапустите сервер 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"
Я выполнил следующее на моей стороне базы данных.
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
Приведенная выше программа выдаст ошибку часового пояса
После имени вашей базы данных вы должны добавить это: ?useTimezone=true&serverTimezone=UTC
, После того как вы сделали ваш код будет работать нормально.
Удачи:)
У меня та же проблема, и я решил ее добавить только "? 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()
Вы можете использовать коннектор 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
Установка времени сервера в формате 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
Это сработало для меня.
на DBeaver 6.0: выберите "Параметры подключения"> "Свойства драйвера"> "Часовой пояс сервера"> "Установить UTC".
Также, в весеннем загрузочном конфиге, пришлось установить нижеприведенное свойство.
JDBC: MySQL:// локальный: / serverTimezone=UTC
Из mysql workbench запустите следующие операторы sql:
- SET @@ global.time_zone = '+00: 00';
- SET @@ session.time_zone = '+00: 00';
с помощью следующих операторов sql проверьте, были ли установлены значения:
SELECT @@ global.time_zone, @@ session.time_zone;
Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/resultout? useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC","root",""))
На самом деле это решение этой проблемы, но не просто копируйте и вставляйте его в свою программу. Если вы просто прочитаете строку, вы найдете "resultout", это имя моей базы данных, и вам нужно будет написать свое.
Есть три строковых компонента: первый - это URL, второй - имя пользователя, а третий - пароль. В предыдущем абзаце мы очистили url. Второй и третий компоненты String, как указано, ваше имя пользователя и пароль, вы должны соответственно изменить.
Спасибо
У меня есть ошибка, похожая на вашу, но мое значение часового пояса сервера - 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 и выполните запрос.
Я добавил следующую строку в свой /etc/mysql/my.cnf
файл:
default_time_zone='+00:00'
Перезагрузили сервер MySQL:
systemctl restart mysql
И это работает как шарм.
У меня была такая же проблема, когда я пытаюсь работать с проектом весенней загрузки на Windows.
URL источника данных должен быть:
spring.datasource.url=jdbc:mysql://localhost/database?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC
Запустите ниже запрос к базе данных 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;
Установка часового пояса по местоположению для приложения весенней загрузки внутри
application.properties
файл в
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", и это не удалось, поэтому по некоторым причинам он не любит летнее время!
мой.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
В моем случае это была тестовая среда, и мне пришлось заставить существующее приложение работать без каких-либо изменений конфигурации и, если возможно, без каких-либо изменений конфигурации MySQL. Мне удалось решить эту проблему, следуя предложению @vinnyjames и изменив часовой пояс сервера на UTC:
ln -sf /usr/share/zoneinfo/UTC /etc/localtime
service mysqld restart
Этого было достаточно для решения проблемы.
Я опаздываю, но если вы боретесь со следующей ошибкой и используете источник данных (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");
Строка подключения работала для меня
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'
}