
Java-библиотека для парсинга, валидации, миграции и описания cron-выражений с поддержкой нескольких форматов (Unix, Quartz, Spring) и человекочитаемого вывода с учётом локали.
Мы определяем crons. И поддерживаем их.
cron-utils — это Java библиотека для определения, разбора, валидации, миграции crons, а также получения человекочитаемых описаний для них. Проект следует Соглашению о семантическом версионировании, предоставляет метаданные OSGi и использует лицензию Apache 2.0.
Загрузка
cron-utils доступна в репозитории Maven central.
<dependency>
<groupId>com.cronutils</groupId>
<artifactId>cron-utils</artifactId>
<version>9.2.1</version>
</dependency>
Для разработчиков Android, cron-utils 7.0.0 предполагает Android 26+. Для более ранних версий Android рассмотрите использование cron-utils 6.0.6. Если используется ScheduleExpression из Java EE, это должно быть предоставлено как runtime-зависимость.
Текущая разработка
В настоящее время мы работаем над обновлением кодовой базы в сторону JDK 16, чтобы обеспечить полную совместимость с JDK 17 после его выхода.
Сейчас мы разрабатываем новое поколение cron-дескрипторов с использованием нейронного перевода! Любые виды вклада приветствуются: от помощи в генерации наборов данных до обучения моделей машинного обучения и утилит для их загрузки! Если заинтересованы, следите за задачей #3.
Возможности
Примеры использования
Ниже представлены несколько примеров. Вы можете найти их и другие в репозитории с примерами, который мы создали для демонстрации библиотек cron-utils!
Создание определений cron
// Определите свой собственный cron: произвольные поля разрешены, последнее поле может быть опциональным
CronDefinition cronDefinition =
CronDefinitionBuilder.defineCron()
.withSeconds().and()
.withMinutes().and()
.withHours().and()
.withDayOfMonth()
.supportsHash().supportsL().supportsW().and()
.withMonth().and()
.withDayOfWeek()
.withIntMapping(7, 0) // мы поддерживаем нестандартные номера с отсчетом не с нуля!
.supportsHash().supportsL().supportsW().and()
.withYear().optional().and()
.instance();
// или возьмите предопределенный экземпляр
cronDefinition = CronDefinitionBuilder.instanceDefinitionFor(QUARTZ);
Создание cron-выражения
// Создайте cron-выражение. CronMigrator гарантирует, что вы остаетесь независимы от cron-провайдера
import static com.cronutils.model.field.expression.FieldExpressionFactory.*;
Cron cron = CronBuilder.cron(CronDefinitionBuilder.instanceDefinitionFor(CronType.QUARTZ))
.withYear(always())
.withDoM(between(SpecialChar.L, 3))
.withMonth(always())
.withDoW(questionMark())
.withHour(always())
.withMinute(always())
.withSecond(on(0))
.instance();
// Получите строковое выражение
String cronAsString = cron.asString(); // 0 * * L-3 * ? *
Разбор
// Создайте парсер на основе предоставленного определения
CronParser parser = new CronParser(cronDefinition);
Cron quartzCron = parser.parse("0 23 * ? * 1-5 *");
...даже мульти-cron выражения! Что скажете о сжатии нескольких crons в одну строку? Вместо написания 0 0 9 * * ? *, 0 0 10 * * ? *, 0 30 11 * * ? * и 0 0 12 * * ? * мы можем обернуть их в 0 0|0|30|0 9|10|11|12 * * ? *
Описание
// Создайте дескриптор для определенной локали
CronDescriptor descriptor = CronDescriptor.instance(Locale.UK);
// Разберите выражение и попросите дескриптор дать описание
String description = descriptor.describe(parser.parse("*/45 * * * * ?"));
// Описание будет: "каждые 45 секунд"
description = descriptor.describe(quartzCron);
// Описание будет: "каждый час в минуту 23 каждый день с понедельника по пятницу"
// что совпадает с описанием для cron ниже:
descriptor.describe(parser.parse("0 23 * ? * MON-FRI *"));
Миграция
// Миграция между cron-библиотеками еще никогда не была такой простой!
// Превратите cron-выражения в другой формат с помощью CronMapper:
CronMapper cronMapper = CronMapper.fromQuartzToCron4j();
Cron cron4jCron = cronMapper.map(quartzCron);
// и чтобы получить строковое представление, мы можем использовать
cron4jCron.asString();//вернет: 23 * * * 1-5
Валидация
cron4jCron.validate()
Расчет времени от/до выполнения
// Получите дату последнего выполнения
ZonedDateTime now = ZonedDateTime.now();
ExecutionTime executionTime = ExecutionTime.forCron(parser.parse("* * * * * ? *"));
ZonedDateTime lastExecution = executionTime.lastExecution(now);
// Получите дату следующего выполнения
ZonedDateTime nextExecution = executionTime.nextExecution(now);
// Время с последнего выполнения
Duration timeFromLastExecution = executionTime.timeFromLastExecution(now);
// Время до следующего выполнения
Duration timeToNextExecution = executionTime.timeToNextExecution(now);