Без загрузки, 100% локально, без аккаунта

Статья

Unix-метки времени и cron-выражения: объяснение

Unix-метка времени является просто целым числом. Cron-выражение состоит просто из пяти полей. Оба постоянно встречаются в серверной разработке и оба предсказуемо вызывают затруднения: первое из-за часовых поясов, второе из-за единицы измерения.

Что такое Unix-метка времени

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

Временная шкала: Unix epoch 1970-01-01 00:00:00 UTC слева, текущая метка времени в середине и граница переполнения 2038 года справа с отметкой максимума знакового 32-bit целого.

Секунды, миллисекунды и проблема 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 рядом с местными датой и временем вашего устройства, так что переход через границу суток, как в этом примере, виден с первого взгляда. Конвертация выполняется полностью в браузере, и ничто, что вы вставляете, никуда не передаётся.

Две календарные сетки рядом для одного и того же значения epoch: сетка UTC выделяет один календарный день, а сетка Нью-Йорка (UTC-4) выделяет предыдущий день, показывая, как местная дата сдвигается назад из-за разницы часовых поясов.

Синтаксис 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 и никогда не покидает устройство.

Инструменты из этой статьи

Частые вопросы

Почему 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 года.