A Java library to parse, validate, migrate crons as well as get human readable descriptions for them. The project follows the Semantic Versioning Convention and uses Apache 2.0 license.
Download
cron-utils is available on Maven central repository.
<dependency>
<groupId>com.cronutils</groupId>
<artifactId>cron-utils</artifactId>
<version>2.0.0</version>
</dependency>
Features
- Create arbitrary cron expressions: you can define your own cron format! Supported fields are: second, minute, hour, day of month, month, day of week, year.
- You can flag last field as optional!
- Supports all cron special characters: * / , -
- Non-standard characters L, W, LW and # are supported as well!
- Question mark (?) is currently replaced for an asterisk (*). Enhanced support will be provided in a future.
- Print to locale specific human readable format (English and Spanish are fully supported. Dutch, French, Italian and Portuguese have basic support).
- Parse and Description process are decoupled: parse once and operate with the result!
- Validate if cron string expressions match a cron definition using CronValidator
- Convert crons between different cron definitions: if you need to migrate expressions, CronMapper may help you!
- Pre-defined definitions for the following cron libraries are provided:
- Obtain last/next execution time as well as time from last execution/time to next execution.
- Need to map constants between different cron/time libraries? Use ConstantsMapper.
Usage Examples
Build cron definitions
//define your own cron: arbitrary fields are allowed and last field can be optional
CronDefinition cronDefinition =
CronDefinitionBuilder.define()
.withSeconds().and()
.withMinutes().and()
.withHours().and()
.withDayOfMonth()
.supportsHash().supportsL().supportsW().and()
.withMonth().and()
.withDayOfWeek()
.withIntMapping(7, 0) //we support non-standard non-zero-based numbers!
.supportsHash().supportsL().supportsW().and()
.withYear().and()
.lastFieldOptional()
.instance();
//or get a predefined instance
cronDefinition = CronDefinitionBuilder.instanceDefinitionFor(QUARTZ);
Parse
//create a parser based on provided definition
CronParser parser = new CronParser(cronDefinition);
Cron quartzCron = parser.parse("0 23 ? * * 1-5 *");
Describe
//create a descriptor for a specific Locale
CronDescriptor descriptor = CronDescriptor.instance(Locale.UK);
//parse some expression and ask descriptor for description
String description = descriptor.describe(parser.parse("*/45 * * * * *"));
//description will be: "every 45 seconds"
description = descriptor.describe(quartzCron);
//description will be: "every hour at minute 23 every day between Monday and Friday"
//which is the same description we get for the cron below:
descriptor.describe(parser.parse("0 23 ? * * MON-FRI *"));
Migrate
//Migration between cron libraries is easy!
//Turn cron expressions into another format by using CronMapper:
CronMapper cronMapper =
new CronMapper(
cronDefinition,
CronDefinitionBuilder.instanceDefinitionFor(CRON4J)
);
Cron cron4jCron = cronMapper.map(quartzCron);
//and to get a String representation of it, we can use
cron4jCron.asString();//will return: 23 * * * 1-5
Validate
//Validate if a string expression matches a cron definition:
CronValidator quartzValidator = new CronValidator(cronDefinition);
//getting a boolean result:
quartzValidator.isValid("0 23 ? * * MON-FRI *");
//or returning same string if valid and raising an exception if invalid
quartzValidator.validate("0 23 ? * * MON-FRI *");
Calculate time from/to execution
//Get date for last execution
DateTime now = DateTime.now();
ExecutionTime executionTime = ExecutionTime.forCron(parser.parse("* * * * * * *"));
DateTime lastExecution = executionTime.lastExecution(now));
//Get date for next execution
DateTime nextExecution = executionTime.timeToNextExecution(now));
//Time from last execution
Duration timeFromLastExecution = executionTime.timeFromLastExecution(now);
//Time to next execution
Duration timeToNextExecution = executionTime.timeToNextExecution(now);
Date and time formatting for humans!
//You no longer need to remember "YYYY-MM-dd KK a" patterns.
DateTimeFormatter formatter =
DateTimeFormatBuilder
.usingLocale(Locale.US)
.createPatternFor("Thursday, June 9, 2011");
String formattedDateTime = formatter.print(lastExecution);
//formattedDateTime will be lastExecution in "dayOfWeek, Month day, Year" format
Map constants between libraries
//Map day of week value from Quartz to JodaTime
int jodatimeDayOfWeek =
ConstantsMapper.weekDayMapping(
ConstantsMapper.QUARTZ_WEEK_DAY,
ConstantsMapper.JODATIME_WEEK_DAY
);
Contribute & Support!
Contributions are welcome! You can contribute by
- star and/or Flattr this repo!
- requesting or adding new features. Check our roadmap!
- enhancing existing code: ex.: provide more accurate description cases
- testing
- enhancing documentation
- providing translations to support new locales
- bringing suggestions and reporting bugs
- spreading the word / telling us how you use it!
Check our page! For stats about the project, you can visit our OpenHUB profile.
Support us donating once or by subscription through Flattr!