Как заставить UNIX_TIMESTAMP не смещать поле даты и времени в разных часовых поясах? - PullRequest
4 голосов
/ 02 октября 2009

Я построил небольшой форум, где пользователи могут публиковать сообщения. Мой сервер находится в Соединенных Штатах, но база пользователей форума находится в Тайване (+ 15 часов).

Когда кто-то отправляет сообщение в форму, я сохраняю время в моей базе данных mySQL в формате ГГГГ-ММ-ДД ЧЧ: ММ: СС. Когда я смотрю в базу данных, время отображает правильное время (время, когда человек в Тайване опубликовал его).

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

Пример:

  1. Я что-то публикую на форуме. Дата на моих наручных часах 2009-10-2 11:24 (тайваньское время)
  2. Я заглядываю в базу данных, и там говорится, что дата 2009-10-2 11:24 утра (одновременно с моими наручными часами. Хорошо!)
  3. Затем, когда я использую UNIX_TIMESTAMP для отображения даты на своем веб-сайте, она отображается как 2009-10-03 16:22 (плохо! Применено смещение)

Есть ли способ заставить UNIX_TIMESTAMP прекратить преобразовывать время (применяя смещение) при запросе даты из базы данных?

Дополнительная информация:
Я использую PHP
Я установил часовой пояс в моем PHP на Тайвань (date.timezone = Asia / Taipei)
Если пользователь находится в другом часовом поясе, чем Тайвань, я хочу, чтобы он преобразовал время в тайбэйское время. Сайт почти на 100% используется в Тайване, поэтому я просто хочу, чтобы тайваньское время показывалось постоянно, даже если они в другом часовом поясе. Я отображаю дату во многих областях вокруг сайта в разных форматах date ().
В основном все работает отлично, за исключением того, что когда я использую UNIX_TIMESTAMP для запроса данных, он применяет смещение ко времени.

Спасибо!

Ответы [ 4 ]

4 голосов
/ 27 мая 2013

MySQL записывает даты «как есть», также читает их так, но UNIX_TIMESTAMP обрабатывает любые входные даты как в вашем местном часовом поясе и преобразует их в метки времени UTC / GMT, то есть будет применено смещение вашего местного часового пояса, теперь, если вы обработаете временные метки возвращаются из MySQL через, например. php date () снова применит ваше местное смещение часового пояса (обратите внимание, что есть также gmtime (), который этого не делает), что приведет к нежелательным результатам.

Но вы можете обойтись этим следующим трюком, который вычтет ваш часовой пояс сеанса до того, как UNIX_TIMESTAMP () применит его, так что вы получите точное число независимо от часового пояса сервера / локального, если вы хотите точно такую ​​же дату в дБ, как если бы это было время по Гринвичу.

mysql> SELECT UNIX_TIMESTAMP(CONVERT_TZ("2013-05-27","GMT",@@session.time_zone));
+--------------------------------------------------------------------+
| UNIX_TIMESTAMP(CONVERT_TZ("2013-05-27","GMT",@@session.time_zone)) |
+--------------------------------------------------------------------+
|                                                         1369612800 |
+--------------------------------------------------------------------+
1 row in set (0.00 sec)

Другое решение - установить для часового пояса сервера или сеанса значение 0 (GMT), чтобы не происходило никаких реальных преобразований.

3 голосов
/ 03 октября 2009

MySQL принимает системный часовой пояс по умолчанию, если не указано иное, он объясняет проблемы, с которыми вы сталкиваетесь; для более подробной информации обратитесь к справочному руководству MySQL time zone . Основываясь на своем прошлом опыте, я пришел к выводу, что UTC - лучший выбор для хранения даты и времени; при отображении его пользователю они преобразуются в часовой пояс пользователя.

Если возможно, измените все записи даты и времени в БД на UTC, настройте часовой пояс в PHP, используя date_default_timezone_set(), и убедитесь, что он правильно преобразован при рендеринге пользователю и при его сохранении в базе данных. Если сохранение значений UTC невозможно, вы можете просто преобразовать их, следуя справочному руководству по часовым поясам так же, как и в UTC.

Что вам нужно сделать, это получить необработанные дату и время из базы данных, а затем использовать PHP DateTime для их преобразования. Взгляните также на DateTimeZone .

2 голосов
/ 08 июня 2012

Лучшее, что я нашел для этой проблемы, это использование:

SELECT UNIX_TIMESTAMP (CONVERT_TZ (<< >>, '+ 15:00', '+ 00:00')) + TIMESTAMPDIFF (секунда, utc_timestamp (), now ())

Пример. Я хочу получить метку времени 31 мая 2012 года в 23:59:59 по местному времени. SELECT UNIX_TIMESTAMP (CONVERT_TZ ('2012-05-31 23:59:59', '+ 15:00', '+ 00:00')) + TIMESTAMPDIFF (секунда, utc_timestamp (), now ())

Таким образом, я получаю метку времени GMT-0, соответствующую местному времени.

1 голос
/ 03 октября 2009

Я нашел возможное решение, которое состоит в том, чтобы просто получить дату из базы данных, не преобразовывая ее в время Unix, а затем просто используя strtotime (); преобразовать его во время Unix. В основном, вместо того, чтобы конвертировать с помощью sql, я конвертирую с использованием php. Единственное, что мне не нравится в этом: strtotime () <Я не уверен, насколько надежна эта функция, и мне нужно перейти и поменять около 100 мест, где я использую UNIX_TIMESTAMP (doh!) </p>

Есть ли другие способы?

...