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