Статья
Unix-метки времени и cron-выражения: объяснение
Unix-метка времени является просто целым числом. Cron-выражение состоит просто из пяти полей. Оба постоянно встречаются в серверной разработке и оба предсказуемо вызывают затруднения: первое из-за часовых поясов, второе из-за единицы измерения.
Что такое Unix-метка времени
Unix-метка времени считает количество секунд, прошедших с 1970-01-01 00:00:00 UTC, точки отсчёта, известной как Unix epoch. Это определение имеет два важных следствия. Во-первых, счёт ведётся в UTC: в самом числе нет встроенного часового пояса. Значение 1718400000 означает один и тот же момент везде на Земле вне зависимости от местонахождения хранящей его системы. Во-вторых, эпоха определена в секундах, а не в других единицах. Значение вроде 1718400000 всегда означает секунды с полуночи 1 января 1970 UTC, если только система или протокол явно не сделали иной выбор. Метки времени лишены часовых поясов намеренно: именно поэтому они полезны для журналов, баз данных и межсистемного обмена, где часы в разных регионах должны однозначно указывать на один и тот же момент.

Секунды, миллисекунды и проблема 2038 года
Многие современные среды выполнения и API используют миллисекунды, а не секунды. Метод Date.now() в JavaScript возвращает миллисекунды, поэтому 1718400000000 обозначает тот же момент, что значение с точностью до секунды 1718400000. При получении незнакомой метки времени величина числа подскажет единицу: 10-значное число почти всегда секунды; 13-значное почти всегда миллисекунды. Проблема 2038 года возникает из другого выбора: хранения метки времени с точностью до секунды в знаковом 32-bit целом числе. Максимальное значение знакового 32-bit целого равно 2147483647, что соответствует 2038-01-19 03:14:07 UTC. После этой секунды счётчик переполнится до большого отрицательного числа, и дата откатится к 1901 году в системах, не обрабатывающих эту границу. Решение: использовать 64-bit хранилище. Большинство современных операционных систем и баз данных уже делают это, однако встроенные системы, сетевые устройства и старые форматы файлов с фиксированной шириной поля остаются в зоне риска.
Перевод эпохи в дату: шаг с часовым поясом
Перевод значения эпохи в читаемую дату требует двух шагов: получить компоненты даты UTC из целого числа, затем применить UTC-смещение для получения местного времени. Сама метка времени содержит UTC. Если спросить, какую дату представляет 1718325000, правильный ответ: 2024-06-14, 00:30 в UTC. В Нью-Йорке (UTC-4 летом) та же секунда приходится на 2024-06-13, 20:30 вечера накануне: меняется дата, а не только час. Именно этот шаг пропускают при получении неверных результатов: разработчик записывает необработанную метку в UTC, инструмент отчётности отображает её в местном времени без конвертации, и дата выглядит сдвинутой на часы или целые сутки. Инструмент «timestamp-converter» на Sunasty явно обрабатывает это: вы вводите значение эпохи, и он показывает дату и время в UTC рядом с местными датой и временем вашего устройства, так что переход через границу суток, как в этом примере, виден с первого взгляда. Конвертация выполняется полностью в браузере, и ничто, что вы вставляете, никуда не передаётся.

Синтаксис cron: пять полей, диапазоны, шаги и списки
Cron-выражение планирует повторяющиеся задания на Unix-подобных системах. Стандартный синтаксис состоит из пяти полей, разделённых пробелами: минута (0-59), час (0-23), день месяца (1-31), месяц (1-12), день недели (0-7, где и 0, и 7 обозначают воскресенье). Звёздочка (*) в поле означает «каждое допустимое значение». Выражение 30 8 * * 1-5 запускается в 08:30 с понедельника по пятницу. Диапазоны используют дефис: 1-5 охватывает значения 1, 2, 3, 4, 5. Списки используют запятые: 1,15 означает 1-е и 15-е. Шаги используют косую черту: */15 в поле минут означает каждые 15 минут (0, 15, 30, 45). Комбинаторы можно совмещать: 0-30/10 означает 0, 10, 20, 30. Одного поля часового пояса в cron нет. Демон читает часы машины, на которой работает, а они настроены на местное время сервера. Если сервер работает по UTC, но разработчик ожидает местное время, задание запускается в неверный час по часам. Практическое правило: воспринимайте cron-расписания как выражения в местном времени сервера и документируйте часовой пояс сервера рядом со строкой cron.
Использование конвертера меток времени локально
Инструмент «timestamp-converter» на Sunasty конвертирует в обоих направлениях: из эпохи в дату и из даты обратно в эпоху. Вы можете вводить значение с точностью до секунды или до миллисекунды; инструмент определяет единицу по величине числа. Он показывает результат в UTC и в собственном локальном часовом поясе вашего устройства рядом друг с другом, вместе с необработанными значениями в секундах и миллисекундах, готовыми для копирования. Кнопка «Now» одним щелчком подставляет текущую метку времени, что даёт быстрый способ узнать текущее Unix-время без открытия терминала. Отдельного выбора часового пояса нет: колонка местного времени всегда отражает часовой пояс, установленный в вашем браузере в данный момент. Всё это работает в браузере. Значение, вставляемое в поле, читается клиентским JavaScript и никогда не покидает устройство.
Инструменты из этой статьи
- Конвертер меток времениКонвертируйте метки времени Unix epoch в человекочитаемые даты (UTC + локальное) и обратно. Автоматически определяет секунды или миллисекунды.
- Разница между датамиПосчитайте дни, недели, месяцы и годы между двумя датами, полностью в браузере, ничего не загружается.
- Парсер cron-выраженийРазберите cron-выражение и просмотрите его ближайшие времена запуска. Приватно, в браузере.
Частые вопросы
Почему JavaScript использует миллисекунды вместо секунд?
Объект Date в JavaScript изначально разрабатывался с поддержкой точности меньше секунды, а миллисекунды дают в тысячу раз большее разрешение, чем секунды, без необходимости в десятичной точке. Компромисс состоит в больших числах: именно поэтому Date.now() возвращает 13-значное число, тогда как большинство серверных меток времени состоит из 10 знаков.
Должен ли каждый сервер с cron работать по UTC?
Нет, но работа серверов по UTC является распространённой практикой именно потому, что устраняет неоднозначность. Когда сервер работает по UTC, cron-выражение вроде 0 2 * * * означает 02:00 UTC, и это время стабильно круглый год. На сервере в поясе с летним временем то же задание срабатывает в разный UTC-момент летом и зимой, а при переводе часов может сработать дважды или пропустить один запуск.
Какой тип хранения безопасен для меток времени после 2038 года?
Знаковое 64-bit целое число хранит метки времени с точностью до секунды вплоть до 292277026596 года, что за пределами любых практических нужд. Большинство современных баз данных по умолчанию хранят метки времени как 64-bit значения. При работе с устаревшей схемой или бинарным форматом файла, использующим 32-bit поля, правильное решение: перейти на 64-bit хранилище до границы 2038 года.