Quartz и стандартный cron: ключевые различия
Краткое руководство по выбору правильного диалекта cron и предотвращению несовпадений парсера.
Открыть расшифровщик QuartzПочему диалект cron имеет значение
Большинство ошибок cron возникают ещё до развёртывания, когда замысел расписания расходится с синтаксисом. Если вы пишете cron-выражение для стандартного 5-полевого парсера и развёртываете его в планировщике на базе Quartz, результат — не просто синтаксическая ошибка. Позиции полей сдвигаются, токены интерпретируются неправильно, и расписание может сработать в совершенно неправильное время или молча сбоить без какой-либо полезной обратной связи.
Путаница возникает из простого факта: единого формата «cron» не существует. Оригинальный Unix crontab использует пять полей (минута, час, день месяца, месяц, день недели). Quartz Scheduler расширяет это до шести или семи полей, добавляя секунды в начало и необязательный год в конец. Оба называются «cron-выражениями», но они структурно несовместимы. Их смешение — причина номер один ошибок планирования, связанных с диалектом.
Эта статья объясняет ключевые различия с практическими примерами, проверками валидации и конкретными действиями в Cronwise. Вставьте любое выражение в расшифровщик Quartz, чтобы мгновенно увидеть его значение.
Структура полей: 5 полей и 7 полей
Самое принципиальное различие между двумя диалектами — количество полей и их позиции. Стандартный cron использует ровно пять полей:
| Позиция | Поле | Допустимые значения |
|---|---|---|
| 1 | Минута | 0-59 |
| 2 | Час | 0-23 |
| 3 | День месяца | 1-31 |
| 4 | Месяц | 1-12 |
| 5 | День недели | 0-7 (0 и 7 = воскресенье) |
Quartz cron добавляет поле секунд в начало и необязательное поле года в конец:
| Позиция | Поле | Допустимые значения |
|---|---|---|
| 1 | Секунды | 0-59 |
| 2 | Минуты | 0-59 |
| 3 | Часы | 0-23 |
| 4 | День месяца | 1-31 |
| 5 | Месяц | 1-12 или JAN-DEC |
| 6 | День недели | 1-7 или SUN-SAT |
| 7 | Год (необязательно) | 1970-2099 |
Этот позиционный сдвиг — самый частый источник кросс-диалектных ошибок. Стандартное выражение 0 9 * * MON (каждый понедельник в 09:00) становится 0 0 9 ? * MON * в Quartz. Если вставить стандартную версию в Quartz-парсер, 0 будет прочитано как секунды, 9 как часы, а * как день месяца, что создаст совершенно другое расписание.
Токены, специфичные для Quartz: ?, L, W и #
Помимо дополнительных полей, Quartz вводит четыре специальных символа, отсутствующих в стандартном cron. Эти токены позволяют выражать паттерны планирования, невозможные в 5-полевом crontab.
Токен ? (без конкретного значения) обязателен в поле дня месяца или дня недели. Quartz не позволяет обоим полям использовать конкретные значения одновременно. Стандартный cron не имеет такого ограничения, поэтому некоторые стандартные выражения нуждаются в реструктуризации для Quartz.
Токен L (последний) указывает на последний день месяца или последнее конкретное вхождение дня недели. Например, L в дне месяца означает последний день (28-31 в зависимости от месяца), а 5L в дне недели означает последний четверг.
Токен W (рабочий день) выбирает ближайший рабочий день к указанному дню месяца. 15W означает рабочий день, ближайший к 15-му. Если 15-е — суббота, задача сработает в пятницу 14-го. Это ценно для планирования по рабочим дням.
Токен # (n-е вхождение) указывает на конкретное вхождение дня недели в месяце. 6#3 означает третью пятницу. Стандартный cron не имеет встроенного способа выразить этот паттерн.
Интерпретация реальных расписаний: параллельные примеры
Параллельный просмотр двух диалектов делает различия наглядными. Вот типовые требования к расписанию в обоих форматах:
| Замысел | Стандартный cron | Quartz cron | Ключевое различие |
|---|---|---|---|
| Каждый день в полночь | 0 0 * * * | 0 0 0 * * ? * | Префикс секунд; ? в дне недели |
| По будням в 09:30 | 30 9 * * 1-5 | 0 30 9 ? * MON-FRI * | Префикс секунд; ? в дне месяца; именованные дни |
| 1-го числа каждого месяца в 06:00 | 0 6 1 * * | 0 0 6 1 * ? * | Префикс секунд; ? заменяет подстановочный знак в дне недели |
| Каждые 15 минут в рабочее время | */15 9-17 * * 1-5 | 0 0/15 9-17 ? * MON-FRI * | Поле секунд; различия синтаксиса шага; обязательный ? |
| Последний день каждого месяца в полдень | Не поддерживается нативно | 0 0 12 L * ? * | Токен L, специфичный для Quartz |
Последняя строка подчёркивает разрыв возможностей. Стандартный cron не может нативно выразить «последний день месяца». Quartz справляется с этим одним токеном L. Это преимущество — причина, по которой многие корпоративные платформы выбирают диалект Quartz, несмотря на его дополнительную сложность.
Крайние случаи и типичные подводные камни
Различия диалектов создают тонкие крайние случаи, которые проходят базовые проверки синтаксиса, но вызывают проблемы во время выполнения:
Несовпадение нумерации дней недели. Стандартный cron использует 0-7, где и 0, и 7 означают воскресенье. Quartz использует 1-7, где 1 — воскресенье, а 7 — суббота. Выражение * * * * 5 (пятница в стандартном cron) становится 0 * * ? * 6 * в Quartz. Ошибка в этом сдвигает задачу на один день.
Отсутствие ? вызывает отклонение. Quartz требует ? ровно в одном из двух полей дней. Использование * в обоих — недопустимо в Quartz, хотя вполне допустимо в стандартном cron.
Двусмысленность поля года. При шести токенах некоторые Quartz-парсеры интерпретируют шестой как день недели, а другие — как год. Cronwise поддерживает явные режимы разбора standard5, withSeconds6 и quartz7 для устранения этой двусмысленности.
Сдвиг часового пояса при миграции диалекта. Смена диалекта cron часто означает смену платформы планировщика, которая может иметь другой часовой пояс по умолчанию. Расписание, корректно работавшее в crontab с настройкой UTC, может сработать в неправильное время в Quartz-планировщике, использующем часовой пояс JVM. Подробнее об этом риске читайте в статье Часовые пояса в cron для глобальных команд.
Выбор правильного диалекта
Решение о диалекте определяется вашей платформой, а не личными предпочтениями. Выбор неправильного формата не просто вызывает ошибки разбора — он может создать молча неверные расписания, которые выглядят допустимо, но срабатывают в неправильное время.
Используйте стандартный 5-полевой cron, когда:
- Ваш планировщик — Unix/Linux cron-демон, systemd-таймер или облачный cron-сервис, принимающий 5-полевой синтаксис.
- Вам не нужна точность менее минуты или продвинутые токены выбора дней.
- Ваша команда работает преимущественно в контексте оболочки или DevOps, где стандартный cron — общий диалект.
Используйте Quartz cron, когда:
- Ваш планировщик — Quartz Scheduler, Spring Boot или другой JVM-фреймворк.
- Вам нужна гранулярность на уровне секунд или токены
L,Wи#для логики последнего дня, ближайшего рабочего дня или n-го дня недели.
Если вы не уверены, какой диалект ожидает ваша платформа, проверьте документацию планировщика на количество полей. Пять полей — стандартный. Шесть или семь полей (начинающихся с секунд) — Quartz. Cronwise автоматически определяет диалект при вставке выражения, но знание ожидаемого формата предотвращает путаницу в источнике.
Применение в рабочем процессе Cronwise
Cronwise предоставляет специализированные инструменты для обоих диалектов, поэтому вам никогда не нужно гадать или мысленно конвертировать между форматами. Вот рекомендуемый рабочий процесс верификации перед развёртыванием любого cron-расписания:
Контрольный список проверки
| Проверка | Почему это важно | Критерий прохождения |
|---|---|---|
| Подтвердите диалект | Неправильный парсер даёт неправильные результаты | Количество полей совпадает с планировщиком (5 или 6/7) |
| Валидируйте выражение | Выявляет синтаксические ошибки и неуместные токены | Нет ошибок или предупреждений в валидации Cronwise |
| Прочитайте описание на понятном языке | Выявляет несовпадение замысла до развёртывания | Описание совпадает с целью планирования |
| Проверьте предварительный просмотр запусков | Конкретные метки времени выявляют крайние случаи | 10 ближайших запусков попадают в ожидаемые окна |
| Проверьте часовой пояс | Часовой пояс планировщика может отличаться от вашего местного | Часовой пояс предварительного просмотра совпадает с продакшен-планировщиком |
| Сохраните и задокументируйте | Повторное использование и аудит для командной работы | Выражение сохранено с описательной заметкой |
Начните с расшифровщика Quartz для расшифровки существующего выражения или используйте генератор Quartz для визуального создания нового. Для стандартного cron расшифровщик на главной и генератор следуют тому же рабочему процессу с 5-полевым синтаксисом.
Итог и дальнейшие шаги
Ключевые различия между Quartz и стандартным cron сводятся к трём областям: количество полей (5 и 6/7), специальные токены (?, L, W, #) и нумерация дней недели (0-7 и 1-7). Все остальные отличия проистекают из этих структурных расхождений. Знание того, какой диалект ожидает ваш планировщик, и валидация против правильного парсера устраняет наиболее распространённый класс ошибок планирования.
Перед развёртыванием любого расписания пройдите контрольный список выше. Подтвердите диалект, проверьте выражение, прочитайте описание на понятном языке, просмотрите метки времени запусков в часовом поясе вашего продакшена и сохраните результат с описательной заметкой для команды.
Для более глубокого изучения читайте наше руководство Специальные символы Quartz для освоения синтаксиса L, W и #. Если часовые пояса вызывают беспокойство, Часовые пояса в cron для глобальных команд охватывает смещения UTC, крайние случаи с летним временем и стратегии планирования с учётом часовых поясов. Все статьи по cron для продолжения обучения.