У меня есть сервер MySQL, установленный в UTC (@@global.time_zone = '+00: 00') и таблица с столбцом DATETIME, в котором хранятся даты в формате UTC. У меня возникают проблемы с получением дат UTC, когда я вызываю хранимую процедуру через JDBC. Пример:
java.util.Date now = new java.util.Date();
sproc = conn.prepareCall("{call TzTestInsert(?)}");
sproc.setTimestamp(1, new java.sql.Timestamp(now.getTime()), Calendar.getInstance(TimeZone.getTimeZone("GMT+00:00")));
sproc.execute();
TzTestInsert sproc просто принимает DATETIME и вставляет его в таблицу.
Я ожидаю, что база данных теперь будет поддерживать мое текущее время в UTC, но на самом деле она содержит текущее время для моего часового пояса.
Если я изменяю sproc, чтобы взять строку, она работает...
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
...
sproc.setString(1, dateFormat.format(now));
но я предпочел бы использовать правильный тип в sproc.
Также работает, если я обойду sproc, но опять же не мое предпочтительное решение...
String sql = "INSERT INTO TzTest VALUES('" + dateFormat.format(now) + "') ;
С исходным sproc у меня такая же проблема, если я использую тип данных TIMESTAMP в sproc и table, что неудивительно с сервером в UTC, так как любые преобразования часовых поясов, специфичные для MySQL TIMESTAMP, должны быть noops.
Вызов sproc из подключения MySQL Workbench работает нормально, например
CALL TzTestInsert(UTC_TIMESTAMP());
Похоже, проблема в JDBC. Я просмотрел различные параметры подключения к часовому поясу и не нашел ничего, что могло бы изменить ситуацию.
Я должен упустить что-то основное - многие люди делают это, правильно?
Решение заключалось в том, чтобы передать драйвер JDBC "useLegacyDatetimeCode = false". См. Mysql bug http://bugs.mysql.com/bug.php?id=15604
Похоже, что они оставили старый код в драйвере для обратной совместимости.