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

Некоторая предыстория:

У меня есть Java 1.6 webapp, работающий на 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

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

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

Ответ 2

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

SET GLOBAL time_zone = '+3:00';

Ответ 3

Если вы используете 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.

Ответ 4

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

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

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

Ответ 5

После прочтения нескольких сообщений на эту тему, тестирования различных конфигураций и на основе некоторых выводов из этой ветки ошибок 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' (подробности в fooobar.com/questions/1511588/...)
  • Для баз данных, настроенных в AWS (веб-сервисы Amazon), автоматически назначается время UTC + 0 по умолчанию (см. Страницу справки AWS здесь)

Ответ 6

Это ошибка в 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 для вашего кода и будьте осторожны с порядком загрузки контейнера. Это может помочь: https://owenou.com/2010/07/20/patching-with-class-shadowing-and-maven.html

  • Если это веб-приложение, более простым решением является создание собственного mysql-connector-java-5.1.37-patched.jar, подставляя .class напрямую в оригинальную банку.

Ответ 7

Я решил поставить ниже строку подключения в URL-адрес

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

Ответ 8

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

Ответ 9

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

    default_time_zone='+03:00'
    
  • И перезагрузите сервер mysql:

    sudo service mysql restart
    

Где +03: 00 мой часовой пояс UTC.

Путь к файлу конфигурации на моем os ubuntu 16.04:

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

ПРЕДУПРЕЖДЕНИЕ: ЕСЛИ ВАША ВРЕМЕННАЯ ЗОНА ИМЕЕТ ЛЕТО И ЗИМНЕЕ ВРЕМЯ. ВЫ ДОЛЖНЫ ИЗМЕНИТЬ UTC В КОНФИГУКЕ, ЧТО ВРЕМЯ ИЗМЕНЕНИЯ. ДВАЖДЫ В ГОД (ПОСЛЕДУЮЩАЯ) ИЛИ УСТАНОВИТЕ КРОНТАБ С СУДО.

Соединение с моим url jdbc:

"jdbc:mysql://localhost/java"

Ответ 10

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

Ответ 11

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

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

Удачи :)

Ответ 12

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

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

Ответ 13

Я использую mysql-connector-java-8.0.13 и имею ту же проблему. Я создал свою базу данных в консоли командной строки и решил эту проблему с помощью решения @Dimitry Rud в командной строке:

SET GLOBAL time_zone = '-6:00';

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

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

Ответ 14

Вы можете использовать коннектор 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

Ответ 15

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

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

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

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

Ответ 16

Из 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;

Ответ 17

У меня также была такая же проблема в LibreOffice Base. Поэтому я просто указал в строке подключения не "летнее время".
**enter image description here**

Я пробовал без "& serverTimezone = MST", но это тоже не удалось.

Я также попытался "& serverTimezone = MDT", и это не удалось, поэтому по какой-то причине ему не нравится переход на летнее время!

Ответ 18

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

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

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

Ответ 19

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

Ответ 20

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

Ответ 21

В моем случае это была тестовая среда, и мне пришлось заставить существующее приложение работать без каких-либо изменений конфигурации и, если возможно, без каких-либо изменений конфигурации MySQL. Мне удалось решить эту проблему, следуя предложению @vinnyjames и изменив часовой пояс сервера на UTC:

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

Этого было достаточно для решения проблемы.

Ответ 22

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

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

Ответ 23

Согласитесь с ответом @bluecollarcoder, но лучше использовать TimeZone.getDefault().getID(); в конце строки подключения:

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

В этом случае параметр Timezone автоматически обновляется в зависимости от часового пояса локального компьютера.

Ответ 24

Решение @Ingvar сработало.

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

Ответ 25

Я также получил тот же Java JDBC под управлением Java в NetBeans. Вот как это исправлено

Я использую Xampp. В кнопке conf Apache я открыл файл httpd.conf и в первой строке набрал

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

В кнопке conf MySQL я открыл файл my.ini и в последней строке набрал "Европа/Афины"

Остановился и запустил Apache и MySQL

Проблема исправлена.

* (Часовой пояс локального механизма отличается, но не проблема.)

Ответ 26

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