IT评测·应用市场-qidao123.com技术社区
标题:
定时任务Cron表达式工具类Cron Util
[打印本页]
作者:
农民
时间:
2025-4-20 11:11
标题:
定时任务Cron表达式工具类Cron Util
依赖
cron-utils的github地点:
https://github.com/jmrozanec/cron-utils
<dependency>
<groupId>com.cronutils</groupId>
<artifactId>cron-utils</artifactId>
<version>9.2.1</version>
</dependency>
复制代码
基本使用
定义cron表达式的支持范围
// 创建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();
// 传入要生成的cron表达式类型获取cron定义
cronDefinition = CronDefinitionBuilder.instanceDefinitionFor(CronType.QUARTZ);
复制代码
支持定时任务的类型:
CRON4J
QUARTZ
UNIX
SPRING
SPRING53
天生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 * ? *
复制代码
各方法对应cron表达式关系:
always:表现*
questionMark:表现?
on:表现具体值
between:表现-,比方,between(0,5)表现0-5
and:表现,,比方,and(on(1),on(5))表现0,5
every:表现/,比方,every(on(2),3)表现2/3
获取cron表达式描述
public class Test {
public static void main(String[] args) {
// 创建cron描述器
CronDescriptor descriptor = CronDescriptor.instance();
// 创建cron定义
CronDefinition cronDefinition = CronDefinitionBuilder.instanceDefinitionFor(QUARTZ);
// 创建cron解析器
CronParser cronParser = new CronParser(cronDefinition);
String describe = descriptor.describe(cronParser.parse("0 0 12 ? * 6"));
System.out.println(describe);
describe = descriptor.describe(cronParser.parse("*/45 * * * * ?"));
System.out.println(describe);
// 设置语言
descriptor = CronDescriptor.instance(Locale.CHINESE);
describe = descriptor.describe(cronParser.parse("0 0 12 ? * 6"));
System.out.println(describe);
describe = descriptor.describe(cronParser.parse("*/45 * * * * ?"));
System.out.println(describe);
}
}
复制代码
// 运行结果:
at 12:00 at Friday day
every 45 seconds
在 12:00 在 星期五 天
每 45 秒
复制代码
校验cron表达式的精确性
public class Test {
public static void main(String[] args) {
CronDefinition cronDefinition = CronDefinitionBuilder.instanceDefinitionFor(QUARTZ);
CronParser cronParser = new CronParser(cronDefinition);
Cron cron = cronParser.parse("0 0 12 ? * 6");
// 校验cron表达式
cron.validate();
cron = cronParser.parse("0 0 12 ? * ?");
cron.validate();
}
}
复制代码
工具类
WeekEnum
定义星期的罗列类信息
@Getter
@AllArgsConstructor
public enum WeekEnum {
SUNDAY(1, "星期天"),
MONDAY(2, "星期一"),
TUESDAY(3, "星期二"),
WEDNESDAY(4, "星期三"),
THURSDAY(5, "星期四"),
FRIDAY(6, "星期五"),
SATURDAY(7, "星期六");
private Integer code;
private String desc;
}
复制代码
CycleTypeEnum
定义要天生的cron表达式类型罗列类信息
@Getter
@AllArgsConstructor
public enum CycleTypeEnum {
MINUTE(1, "分钟"),
HOUR(2, "小时"),
DAY(3, "日"),
WEEK(4, "周"),
MONTH(5, "月"),
QUARTER(6, "季度"),
YEAR(7, "年");
private Integer code;
private String desc;
}
复制代码
RepeatRuleEnum
定义要天生月、季度的cron表达式循环规则罗列类信息
@Getter
@AllArgsConstructor
public enum RepeatRuleEnum {
WEEK(1, "周"),
DATE(2, "日期");
private Integer code;
private String desc;
}
复制代码
CronDto
定义cron表达式工具类的请求体信息
@Data
public class CronDto {
/**
* 周期类型 minute:分钟 hour: 小时; day: 天; week: 周; month: 月; quarter: 季; year: 年
*/
private Integer cycleType;
/**
* 执行时间
*/
private LocalDateTime executionTime;
/**
* 指定一周哪几天
*/
private List<Integer> weekDays;
/**
* 指定一个月哪几天
*/
private List<Integer> monthDays;
/**
* 指定一年哪几月
*/
private List<Integer> quartzMonths;
/**
* 一周的星期几
*/
private Integer dayOfWeek;
/**
* 第几周
*/
private Integer week;
/**
* 重复规则:周 天
*/
private Integer repeatRule;
}
复制代码
CronUtils
根据年、月、日、时、分、秒、星期、季度实现不同的cron表达式
注意:天生年、月、季度的cron表达式时可以根据日或者星期额外判定
public class CronUtils {
/**
* 星期
*/
private static final List<Integer> WEEKS = Arrays.stream(WeekEnum.values()).map(WeekEnum::getCode).collect(Collectors.toList());
public static String createCron(CronDto cronDto) {
Integer cycleType = cronDto.getCycleType();
LocalDateTime executionTime = cronDto.getExecutionTime();
CronBuilder cronBuilder = CronBuilder.cron(CronDefinitionBuilder.instanceDefinitionFor(CronType.QUARTZ));
// 每分钟一次
if (Objects.equals(CycleTypeEnum.MINUTE.getCode(), cycleType)) {
return getSecondCron(cronBuilder, executionTime);
}
// 每小时一次
if (Objects.equals(CycleTypeEnum.HOUR.getCode(), cycleType)) {
return getMinuteCron(cronBuilder, executionTime);
}
// 每日一次
if (Objects.equals(CycleTypeEnum.DAY.getCode(), cycleType)) {
return getDayCron(cronBuilder, executionTime);
}
// 每周一次
if (Objects.equals(CycleTypeEnum.WEEK.getCode(), cycleType)) {
return getWeekCron(cronDto, cronBuilder, executionTime);
}
// 每月一次
if (Objects.equals(CycleTypeEnum.MONTH.getCode(), cycleType)) {
return getMonthCron(cronDto, cronBuilder, executionTime);
}
// 每季度一次
if (Objects.equals(CycleTypeEnum.QUARTER.getCode(), cycleType)) {
return getQuarterCron(cronDto, cronBuilder, executionTime);
}
// 每年一次
if (Objects.equals(CycleTypeEnum.YEAR.getCode(), cycleType)) {
return getYearCron(cronBuilder, executionTime);
}
return "";
}
public static String getYearCron(CronBuilder cronBuilder, LocalDateTime executionTime) {
return cronBuilder.withSecond(on(executionTime.getSecond()))
.withMinute(on(executionTime.getMinute()))
.withHour(on(executionTime.getHour()))
.withDoM(on(executionTime.getDayOfMonth()))
.withMonth(on(executionTime.getMonthValue()))
.withDoW(questionMark())
.instance()
.asString();
}
public static String getQuarterCron(CronDto cronDto, CronBuilder cronBuilder, LocalDateTime executionTime) {
List<FieldExpression> flist = new ArrayList<>();
cronDto.getQuartzMonths().forEach(e -> flist.add(FieldExpressionFactory.on(e)));
return cronBuilder.withSecond(on(executionTime.getSecond()))
.withMinute(on(executionTime.getMinute()))
.withHour(on(executionTime.getHour()))
.withDoM(questionMark())
.withMonth(and(flist))
.withDoW(on(WEEKS.get(cronDto.getDayOfWeek()), SpecialChar.HASH, cronDto.getWeek()))
.instance()
.asString();
}
public static String getMonthCron(CronDto cronDto, CronBuilder cronBuilder, LocalDateTime executionTime) {
Integer repeatRule = cronDto.getRepeatRule();
// 按周
if (Objects.equals(RepeatRuleEnum.WEEK.getCode(), repeatRule)) {
List<FieldExpression> weekDays = new ArrayList<>();
if (!CollectionUtils.isEmpty(cronDto.getWeekDays())) {
cronDto.getWeekDays().forEach(e -> weekDays.add(FieldExpressionFactory.on(WEEKS.get(cronDto.getDayOfWeek()),
SpecialChar.HASH, e)));
}
return cronBuilder.withSecond(on(executionTime.getSecond()))
.withMinute(on(executionTime.getMinute()))
.withHour(on(executionTime.getHour()))
.withDoM(questionMark())
.withMonth(always())
.withDoW(CollectionUtils.isEmpty(weekDays) ? on(WEEKS.get(cronDto.getDayOfWeek()), SpecialChar.HASH,
cronDto.getWeek()) : and(weekDays))
.instance()
.asString();
}
// 按天
if (Objects.equals(RepeatRuleEnum.DATE.getCode(), repeatRule)) {
List<FieldExpression> monthDays = new ArrayList<>();
cronDto.getMonthDays().forEach(e -> monthDays.add(FieldExpressionFactory.on(e)));
return cronBuilder.withSecond(on(executionTime.getSecond()))
.withMinute(on(executionTime.getMinute()))
.withHour(on(executionTime.getHour()))
.withDoM(and(monthDays))
.withMonth(always())
.withDoW(questionMark())
.instance()
.asString();
}
return "";
}
public static String getWeekCron(CronDto cronDto, CronBuilder cronBuilder, LocalDateTime executionTime) {
List<FieldExpression> weekDays = new ArrayList<>();
cronDto.getWeekDays().forEach(e -> weekDays.add(FieldExpressionFactory.on(e)));
return cronBuilder.withSecond(on(executionTime.getSecond()))
.withMinute(on(executionTime.getMinute()))
.withHour(on(executionTime.getHour()))
.withDoM(questionMark())
.withMonth(always())
.withDoW(and(weekDays))
.instance()
.asString();
}
public static String getDayCron(CronBuilder cronBuilder, LocalDateTime executionTime) {
return cronBuilder.withSecond(on(executionTime.getSecond()))
.withMinute(on(executionTime.getMinute()))
.withHour(on(executionTime.getHour()))
.withDoM(always())
.withMonth(always())
.withDoW(questionMark())
.instance()
.asString();
}
public static String getMinuteCron(CronBuilder cronBuilder, LocalDateTime executionTime) {
return cronBuilder.withSecond(on(executionTime.getSecond()))
.withMinute(on(executionTime.getMinute()))
.withHour(always())
.withDoM(always())
.withMonth(always())
.withDoW(questionMark())
.instance()
.asString();
}
public static String getSecondCron(CronBuilder cronBuilder, LocalDateTime executionTime) {
return cronBuilder.withSecond(on(executionTime.getSecond()))
.withMinute(always())
.withHour(always())
.withDoM(always())
.withMonth(always())
.withDoW(questionMark())
.instance()
.asString();
}
}
复制代码
使用案例
public class Test {
public static void main(String[] args) {
CronDto cronDto = new CronDto();
cronDto.setCycleType(1);
cronDto.setExecutionTime(LocalDateTime.now());
String cron = createCron(cronDto);
System.out.println(cron);
cronDto.setCycleType(2);
cron = createCron(cronDto);
System.out.println(cron);
cronDto.setCycleType(3);
cron = createCron(cronDto);
System.out.println(cron);
cronDto.setCycleType(4);
cronDto.setWeekDays(Arrays.asList(1, 2));
cron = createCron(cronDto);
System.out.println(cron);
cronDto.setCycleType(5);
cronDto.setRepeatRule(1);
cronDto.setDayOfWeek(1);
cron = createCron(cronDto);
System.out.println(cron);
cronDto.setCycleType(5);
cronDto.setRepeatRule(1);
cronDto.setWeek(1);
cronDto.setDayOfWeek(1);
cronDto.setWeekDays(null);
cron = createCron(cronDto);
System.out.println(cron);
cronDto.setCycleType(5);
cronDto.setRepeatRule(2);
cronDto.setMonthDays(Arrays.asList(1, 2));
cron = createCron(cronDto);
System.out.println(cron);
cronDto.setCycleType(6);
cronDto.setQuartzMonths(Arrays.asList(1, 2));
cron = createCron(cronDto);
System.out.println(cron);
cronDto.setCycleType(7);
cron = createCron(cronDto);
System.out.println(cron);
}
}
复制代码
// 运行结果:
14 * * * * ?
14 28 * * * ?
14 28 9 * * ?
14 28 9 ? * 1,2
14 28 9 ? * 2#1,2#2
14 28 9 ? * 2#1
14 28 9 1,2 * ?
14 28 9 ? 1,2 2#1
14 28 9 19 11 ?
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
欢迎光临 IT评测·应用市场-qidao123.com技术社区 (https://dis.qidao123.com/)
Powered by Discuz! X3.4