Согласование временных зон между приложением и mysql.

Достаточно избитая во всевозможных блогах, в постах на хабре тема. Даже на офф сайте даны разъяснения и достаточно пруф линков. И все же есть несколько граблей, на который можно наступить, о которых мало где написано.

И так представим ситуацию, когда у нас есть алгоритм, например кеширования, который в своей основе проверяет время жизни закешированного ключа по некоторому логу в базе данных. Тогда мы напишем что-то вроде этого на псевдокоде, похожем на php

Как-то так. И почему-то все запросы берутся из кеша, что мы видим в phpmemcachedadmin (если конечно используется memcached), но все равно задачи отрабатывают по полной. 
Это скажем легкий пример, более простой когда просто приходится писать костыли, чтобы согласовать временные зоны сервера и php кода.

Конечно лучшим вариантом будет, когда есть доступ к root на серверах. Тогда, как советуют везде, есть несколько вариантов.

Установка временной зоны в php

или в php.ini

или в htaccess

 

А для mysql обычно советуют отправить запрос при инициализации приложения для установки .

Так же иногда советуют добавить настройку в mysql/my.cnf

 

При этом подразумевается, что временные зоны выглядят как-то так: Europe/Moscow, Europe/Kiev.

Но это в том случае, если пользователь работает на хорошо настроенном хостинге.
При попытке установить default-time-zone=’Europe/Moscow’ можно поймать ошибку, что нету такой зоны. :)

Дело в том, что изначально параметр default-time-zone принимает значения вида “+06:00”, “-04:00”. А чтобы сработали человекопонятные названия зон, они должны быть занесены в таблицы mysql.time_zone*. Много их.
На офф сайте Mysql дает пояснения как заполнить их автоматически, если они не заполнены, с помощью утилиты.

И вот все вышеперечисленное было сделано. И вот все должно быть хорошо, даты пишутся с одинаковыми значениями по выводу date() в php и в табличках mysql.
А когда пытается отработать вышеприведенный пример с кешем, получается разница в час. Все дело в том, что при доставании из базы значения timelimit вызывается ф-я UNIX_TIMESTAMP(), которая приводит время в соответствии с системной временной зоной.

За этими всеми советами скрыто неведение, как же все таки устроены настройки временных зон в системе и mysql. Хотя с mysql уже понятно, а вот в системе (по крайней мере в ) за зоны отвечает пакет  tzdata. И не смотря на то, что по мануалу временные зоны были заполнены в mysql из системных 

все равно наблюдается расхождение на час. Дело все в том, что сервер может быть настроен на переход на “зимнее время”, отсюда все проблемы. Что же делать?

Теперь все будет работать правильно.