Вечерний коммит

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"

Отдельно про перевод часов

В Москве стрелки не переводят, но серверы и коллеги бывают в разных местах. Там, где есть летнее время, один ночной час раз в год пропадает, а другой повторяется. Задачу на это окно — обычно между часом и тремя ночи — лучше не ставить вовсе.

Я в итоге выбрал первый способ. Комментарий с местным временем читается с первого взгляда, и переносить расписание на другой сервер не страшно.