Różnica w czasie - błędna godzina zapisu (i odczytu)

0

Cześć
Mam aplikację w SpringBoot, która wystawia tylko serwisy RESTowe; jeden do umieszczania danych (/putRecord), pozostałe do ich wyciągania według zadanych w URL parametrów (np. /showRecords...)
Aplikacja jest deployowana na serwerze we Włoszech (Aruba), tam też stoi baza danych MySQL (ta sama maszyna).
Problem: po wywołaniu serwisu zapisującego (powiedzy dziś o godzinie 1600) i wejściu przez MySQL Workbench celem weryfikacji, w kolumnie date (Date z czasem) rzeczywiście mam godzinę 1600. Po zalogowaniu lokalnie z serwera na bazkę i sprawdzeniu tabel też jest to godzina 1600, ale po wylistowaniu wszystkich wpisów w tabeli za pomocą GETa (i przeparsowaniu z epocha) godzina dodania rekordu to 1400. Czyli mamy 2h różnicy (UTC <-> CEST)

Data z sewera:

Wed May 24 14:09:30 CEST 2017
cat /etc/timezone
Europe/Warsaw

(zmieniłem z Europe/Rome)

Dane z serwera bazy MySQL:

mysql> SELECT TIMEDIFF(NOW(), UTC_TIMESTAMP);
+--------------------------------+
| TIMEDIFF(NOW(), UTC_TIMESTAMP) |
+--------------------------------+
| 02:00:00                       |
+--------------------------------+
1 row in set (0.01 sec)
mysql> SELECT @@global.time_zone;
+--------------------+
| @@global.time_zone |
+--------------------+
| SYSTEM             |
+--------------------+
1 row in set (0.00 sec)
mysql> select now();
+---------------------+
| now()               |
+---------------------+
| 2017-05-24 14:11:14 |
+---------------------+
1 row in set (0.00 sec)

Wersja connectora MySQL (w wersjach poniżej były bugi z TimeZone ale ta ponoc jest pierwszą stabilną):

Maven: mysql:mysql-connector-java:5.1.39

Próbowałem też mieszać z connection stringiem:
spring.datasource.url=jdbc//x.x.x.x:3306/pi?autoReconnect=true&useSSL=false&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC

Ale *serverTimezone *nie rozpoznaje CEST a ustawianie CET nic nie zmieniało (GMT zresztą też nic nie zmienia).

Przestawianie timezone w bazie też wydaje się nie mieć żadnego wpływu na zwracany czas:
SET @@global.time_zone = '+2:00';

Na wszelki wypadek napisałem chamską metodę na dodawanie 2 godzin, ale niechciałbym jej wykorzystywać:
Date newDate = DateUtils.addHours(new Date(), 2);

Czy ktoś ma jakiś pomysł?

0

MySQL ma wsparcie dla stref czasowych, obsługuje osobną dla każdego połączenia.
https://dev.mysql.com/doc/refman/5.5/en/time-zone-support.html

0

A sprawy nie powinno załatwić?

mysql> SELECT @@global.time_zone, @@session.time_zone;
+--------------------+---------------------+
| @@global.time_zone | @@session.time_zone |
+--------------------+---------------------+
| SYSTEM             | SYSTEM              |
+--------------------+---------------------+
1 row in set (0.00 sec)

The value 'SYSTEM' indicates that the time zone should be the same as the system time zone.

$ date
Wed May 24 14:32:49 CEST 2017
cat /etc/timezone
Europe/Warsaw

*--default-time-zone=timezone
Set the default server time zone. This option sets the global time_zone system variable. If this option is not given, the default time zone is the same as the system time zone (given by the value of the system_time_zone system variable. *

show global variables like '%zone%';
+------------------+--------+
| Variable_name    | Value  |
+------------------+--------+
| system_time_zone | CEST   |
| time_zone        | SYSTEM |
+------------------+--------+

EDIT:
Dodałem do: /etc/mysql/my.cnf

[mysqld_multi]
default-time-zone='+02:00'

Restart usługi i efektu brak.

0

Z moich obserwacji wynika, że mysql zarówno przy zapisie jak i przy odczycie daty bierze pod uwagę time_zone bieżącej sesji. Na początek mógłbyś zrobić z konsoli mysql:

set time_zone='+00:00';
select top 1 time from tab;

Dowiesz się, jak zapisał Ci się czas w bazie danych. Później pozostaje już tylko zadbać o to, by sesja javova mysql miała odpowiedni time_zone. Może wystarczy odpalić query set time_zone=.... Wydaje mi się, że globalnymi ustawieniami mysql nie musisz się wtedy w ogóle przejmować.

0

Rozwiązaniem było, zamiast:

useLegacyDatetimeCode=false

dać:

useLegacyDatetimeCode=true

1 użytkowników online, w tym zalogowanych: 0, gości: 1