Mysql: конвертировать БД из местного времени в UTC - PullRequest
13 голосов
/ 22 апреля 2010

Мне нужно преобразовать существующую (поля даты и времени) из местного времени в UTC.

Значения хранятся до даты и времени на сервере с часовым поясом CET (+1) (с летним временем +2). При выборе данных я использую UNIX_TIMESTAMP(), который магическим образом компенсирует все, то есть сдвиг часового пояса и dst (если я прочитал документы правильно).

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

Простое вычитание -1 H не сработает, так как летнее время + 2.

Есть идеи для умного способа сделать это? (используя sql или какой-либо скрипт lang)

Ответы [ 3 ]

26 голосов
/ 22 апреля 2010

Сначала вам нужно убедиться, что таблица mysql.time_zone_name заполнена. Если он пуст, вы можете следовать инструкциям на этой странице, чтобы заполнить его:

http://dev.mysql.com/doc/refman/5.1/en/time-zone-support.html

Обычно это так же просто, как запускать такую ​​команду в оболочке:

mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u root mysql

После заполнения этой таблицы вы можете использовать функцию CONVERT_TZ (), чтобы обновить существующие значения в БД:

http://dev.mysql.com/doc/refman/5.1/en/date-and-time-functions.html#function_convert-tz

Вот два примера, показывающих, как он конвертирует время из CET в UTC зимой и летом:

mysql> SELECT CONVERT_TZ('2010-01-22 12:00:00','CET','UTC');
+-----------------------------------------------+
| CONVERT_TZ('2010-01-22 12:00:00','CET','UTC') |
+-----------------------------------------------+
| 2010-01-22 11:00:00                           |
+-----------------------------------------------+
1 row in set (0.00 sec)

mysql> SELECT CONVERT_TZ('2010-07-22 12:00:00','CET','UTC');
+-----------------------------------------------+
| CONVERT_TZ('2010-07-22 12:00:00','CET','UTC') |
+-----------------------------------------------+
| 2010-07-22 10:00:00                           |
+-----------------------------------------------+
1 row in set (0.00 sec)
6 голосов
/ 04 августа 2013

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

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

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

Простой пример. Давайте создадим встречу в следующем году в Берлине, Германия. Сегодня мы согласны с тем, что мы хотим встретиться в 12:00 1 июля 2014 года на Александерплац. Эта дата будет переведена в 10:00 UTC в этот день.

Теперь, если какое-либо правительство решит отказаться от перехода на летнее время в 2014 году, у вас возникнет проблема, решив, следует ли вам появляться в 12:00 по местному времени или в 11:00 по местному времени, потому что преобразование обратно из UTC приведет к другому местному времени.

Если вы сохранили исходную дату «2014-07-01 12:00 Европа / Берлин», вы будете там в это время в полдень, как и все остальные.

4 голосов
/ 11 сентября 2016

На исходном сервере вы можете использовать одно из следующих выражений внутри запроса UPDATE:

CONVERT_TZ(your_datetime_field,'SYSTEM','UTC') CONVERT_TZ(your_datetime_field,@@global.time_zone,'UTC')

В качестве альтернативы на целевом сервере, если вы знаете часовой пояс исходного сервера (например, «Европа / Берлин»), вы можете использовать одно из следующих выражений:

CONVERT_TZ(your_datetime_field,'Europe/Berlin','UTC') CONVERT_TZ(your_datetime_field,'Europe/Berlin',@@global.time_zone)

...