Cron и часовые пояса: почему отчёт пришёл в полдень
Поставил задачу на девять утра, чтобы отчёт лежал в почте к началу дня. Отчёт пришёл в двенадцать. Причина простая, но наступаю на неё не первый раз.
Cron считает время по часовому поясу сервера. Сервер у меня в UTC, я в Москве, разница три часа. Строка 0 9 * * * честно сработала в девять — по UTC.
Способ первый: пересчитать и подписать
0 6 * * * /opt/report/run.sh # 09:00 по Москве
Сервер остаётся в UTC, время в расписании пересчитываю руками, местное пишу в комментарии. Способ скучный, зато работает в любой системе.
Способ второй: CRON_TZ
CRON_TZ=Europe/Moscow
0 9 * * * /opt/report/run.sh
Переменная в начале файла задаёт пояс для расписания. Её понимает cronie. В других реализациях cron поддержки может не быть, поэтому сначала загляните в man 5 crontab на своём сервере.
Способ третий: таймер systemd
[Timer]
OnCalendar=*-*-* 09:00:00 Europe/Moscow
Пояс пишется прямо в расписании. Проверить, когда таймер сработает в следующий раз, можно без ожидания:
systemd-analyze calendar "*-*-* 09:00:00 Europe/Moscow"
Отдельно про перевод часов
В Москве стрелки не переводят, но серверы и коллеги бывают в разных местах. Там, где есть летнее время, один ночной час раз в год пропадает, а другой повторяется. Задачу на это окно — обычно между часом и тремя ночи — лучше не ставить вовсе.
Я в итоге выбрал первый способ. Комментарий с местным временем читается с первого взгляда, и переносить расписание на другой сервер не страшно.