Некоторые проблемы с часовыми поясами в PHP некоторое время были у меня в голове, и мне было интересно, есть ли лучшие способы справиться с этим, чем то, что я делаю в настоящее время.
Все проблемы связаны с переформатированием дат, хранящихся в базе данных:
При работе с сайтом, который должен поддерживать несколько часовых поясов (для пользователей), чтобы нормализовать время хранения часовых меток в часовом поясе, я всегда сохраняю его с часовым поясом сервера, используя атрибут CURRENT_TIMESTAMP
или функцию NOW()
.
Таким образом, мне не нужно учитывать, какой часовой пояс был установлен для PHP при вводе метки времени (поскольку функции времени PHP поддерживают часовой пояс). Для каждого пользователя, в соответствии с его предпочтениями, я устанавливаю часовой пояс где-то в моем файле начальной загрузки, используя:
date_default_timezone_set($timezone);
Когда я пытаюсь отформатировать даты с помощью функции php date()
, необходимо выполнить какое-либо преобразование, поскольку MySQL в настоящее время хранит метку времени в формате Y-m-d H:i:s
. Без учета часового пояса вы можете просто запустить:
$date = date($format,strtotime($dbTimestamp));
Проблема в том, что date()
и strtotime()
являются функциями, учитывающими часовой пояс, что означает, что если часовой пояс PHP установлен не так, как часовой пояс сервера, смещение часового пояса будет применяться дважды (вместо одного, как хотелось бы). ).
Чтобы справиться с этим, я обычно получаю временные метки MySQL, используя функцию UNIX_TIMESTAMP()
, которая не учитывает часовой пояс, что позволяет my применять date()
непосредственно к нему - таким образом применяя смещение часового пояса только один раз.
Мне не очень нравится этот хак, так как я больше не могу получать эти столбцы, как обычно, или использую *
для извлечения всех столбцов (иногда это значительно упрощает запросы). Кроме того, иногда просто невозможно использовать UNIX_TIMESTAMP()
(особенно при использовании пакетов с открытым исходным кодом без особых абстракций для составления запросов).
Другая проблема возникает при сохранении временной метки, когда использование CURRENT_TIMESTAMP
или NOW()
не является опцией - при сохранении сгенерированной PHP временной метки будет храниться ее со смещением часового пояса, которого я хотел бы избежать.
Возможно, мне здесь не хватает чего-то действительно базового, но до сих пор я не смог придумать общего решения для решения этих проблем, поэтому я вынужден рассматривать их в каждом конкретном случае. Ваши мысли очень приветствуются