Yii2. Согласование временных зон между MySQL и PHP
Часто на хостингах встречается проблема, что время в БД MySQL отличается от серверного. Это приводит к тому, что вызов функции типа NOW(), CURRENT_TIME() или CURRENT_TIMESTAMP() будут возвращать "неправильные" значения и будет расхождение времени между БД MySQL и сервером.
Чтобы проверить текущую временную зону MySQL, нужно выполнить запрос:
SHOW VARIABLES LIKE '%zone%';
SELECT @@global.time_zone, @@session.time_zone;
Чтобы посмотреть текущее время сервера БД:
SELECT CURRENT_TIME();
Для того что бы нам синхронизировать серверное время и время в базе данных, нам надо непосредственно указать временную зону для нее, используя запрос вида: SET time_zone="UTC" или SET time_zone="+03:00", в котором мы указываем нужную нам временную зону. Но запрос нужно посылать каждый раз когда вы подключаетесь к базе данных.
В Yii2 есть компонент DB который отвечает за подключение к БД и в нем есть событие "afterOpen" которое вызывается после подключения к БД. В обработчике этого события мы как раз и можем выполнить наш запрос который установит значение временной зоны. См. пример конфигурации компонента:
return [
'components' => [
'db' => [
...
'on afterOpen' => function($event) {
$event->sender->createCommand("SET time_zone='Europe/Moscow';")->execute();
},
...
],
]
];
Вопросы и ответы
Q: Что делать если получается MySQL ошибка вида Unknown or incorrect time zone: 'Europe/Moscow' !?
A: Нужно создать базу timezone в MySql сервере выполнив в консоли:
mysql_tzinfo_to_sql/usr/share/zoneinfo|mysql -u root mysql -p