Работа с PHP-сервером и сервером MySQL в разных часовых поясах
Вопрос
Для тех из нас, кто использует стандартные пакеты общего хостинга, такие как GoDaddy или Network Solutions, как вы обрабатываете преобразования даты и времени, когда ваш хостинг-сервер (PHP) и сервер MySQL находятся в разных часовых поясах?
Кроме того, есть ли у кого-нибудь рекомендации по определению того, в каком часовом поясе находится посетитель вашего сайта, и соответствующему манипулированию переменной datetime?
Решение
Начиная с версии PHP 5.1.0, вы можете использовать date_default_timezone_set() функция для установки часового пояса по умолчанию, используемого всеми функциями даты и времени в скрипте.
Для MySQL (цитируется по Поддержка часовых поясов сервера MySQL страница)
До MySQL 4.1.3 сервер работал только в системном часовом поясе, установленном при запуске.Начиная с MySQL 4.1.3, сервер поддерживает несколько настроек часового пояса, некоторые из которых могут быть изменены во время выполнения.
Вас интересует настройка часовых поясов для каждого соединения, которые вы бы использовали в начале ваших сценариев
SET timezone = 'Europe/London';
Что касается определения настройки часового пояса клиента, вы могли бы использовать немного JavaScript, чтобы получить и сохранить эту информацию в файле cookie и использовать ее при последующих чтениях страницы для вычисления правильного часового пояса.
//Returns the offset (time difference) between Greenwich Mean Time (GMT)
//and local time of Date object, in minutes.
var offset = new Date().getTimezoneOffset();
document.cookie = 'timezoneOffset=' + escape(offset);
Или же вы могли бы предложить пользователям самим устанавливать свои часовые пояса.
Другие советы
Храните все в формате UTC.Вы можете выполнять преобразования на уровне клиента или на стороне сервера, используя настройки клиента.
СОГЛАСНО ответу Желько Живковича, дескрипторы часовых поясов, такие как "Европа / Лондон", работают только в том случае, если администратор MySQL добавил таблицы часовых поясов в систему и постоянно их обновляет.
В противном случае вы ограничены числовыми смещениями, такими как "-4:00".К счастью, формат php date ('P') предоставляет это (начиная с 5.1.3).
Итак, скажем, в файле конфигурации приложения у вас может быть
define('TZ', 'US/Pacific');
....
if (defined('TZ') && function_exists('date_default_timezone_set')) {
date_default_timezone_set(TZ);
$mdb2->exec("SET SESSION time_zone = " . $mdb2->quote(date('P')));
}
Это означает, что PHP и MySQL согласуют, какое смещение часового пояса использовать.
Всегда используйте ВРЕМЕННУЮ МЕТКУ для хранения значений времени.Столбец фактически сохраняется как UNIX_TIME (epoch), но неявно преобразуется из текущего смещения time_zone при записи и обратно при чтении.
Если вы хотите отображать время для пользователей в других часовых поясах, то вместо глобального определения() задайте их заданный часовой пояс в приведенном выше примере.Значения временных меток будут автоматически преобразованы MySQL к тому времени, когда ваше приложение увидит результирующий набор (что иногда может быть проблемой, если вам действительно нужно знать исходный часовой пояс события, тогда оно должно быть в другом столбце)
а что касается "почему бы просто не сохранить все времена как int", это лишает вас возможности сравнивать и проверять даты, и означает, что вы всегда приходится преобразовывать представление даты на уровне приложения (и это неприятно для глаз, когда вы смотрите на данные напрямую - быстро, что произошло на 1254369600?)
Я сохраняю все свои даты как bigint из-за того, что раньше у меня были проблемы с типом DateTime.Я сохраняю в нем результат PHP-функции time (), теперь они считаются находящимися в одном часовом поясе :)
В php установите часовой пояс с помощью в файле php.ini: ini_set("date.timezone", "America/Los_Angeles");
или на конкретной странице вы можете сделать следующее: date_default_timezone_set("America/Los_Angeles");
В mysql вы можете сделать следующее: SET GLOBAL time_zone = 'America/Los_Angeles';