Установка правильной временной зоны в php и mysql
Как согласовать часовые пояса PHP и MySQL и не перепутать момент события с местным временем.

PHP показывает одно время, MySQL — другое. Настройки у них независимые, поэтому изменение date.timezone не меняет часовой пояс соединения с базой. Сначала решим, что хранится в поле: момент события или местная дата со временем. После этого настроим обе стороны и проверим запись вместе с чтением.
Настройка PHP
date_default_timezone_set('Europe/Moscow');
echo date_default_timezone_get();Функция задаёт часовой пояс по умолчанию для соответствующих операций PHP. В конфигурации также существует date.timezone. Явный объект DateTimeZone позволяет выбрать пояс для отдельного преобразования, не меняя общее поведение приложения.
Настройка сеанса MySQL
SET SESSION time_zone = '+00:00';
SELECT @@session.time_zone, NOW(), UTC_TIMESTAMP();Для именованного пояса, например Europe/Moscow, серверу нужны корректно загруженные таблицы часовых поясов. Числовое смещение не описывает исторические переходы и правила летнего времени. Параметр SESSION относится к текущему соединению, поэтому его нужно учитывать при создании и повторном использовании пула.
Тип столбца имеет значение
TIMESTAMP выполняет преобразования с учётом часового пояса сеанса; DATETIME хранит календарное представление без такого автоматического преобразования. Эти типы нельзя считать взаимозаменяемыми. Выбор зависит от смысла данных и допустимого диапазона.
Для момента события часто удобно согласованное хранение в UTC и преобразование на границе отображения. Для расписания «каждый день в девять по Москве» нужно сохранить и календарное правило, и зону. Один сдвиг в секундах не выражает полную задачу.
Возьмите заранее известную дату и проведите её через запись, чтение и показ. Проверьте переход суток и, если это важно, историческую дату. Не компенсируйте ошибку прибавлением трёх часов: сначала найдите, на каком шаге часовой пояс уже был применён.
