依赖

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);

支持定时任务的类型:

  1. CRON4J
  2. QUARTZ
  3. UNIX
  4. SPRING
  5. 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表达式关系:

  1. always:表示*
  2. questionMark:表示?
  3. on:表示具体值
  4. between:表示-,例如,between(0,5)表示0-5
  5. and:表示,,例如,and(on(1),on(5))表示0,5
  6. 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 ?

定时任务Cron表达式工具类Cron Util的更多相关文章

  1. Thymeleaf 表达式工具类

    Thymeleaf默认提供了丰富的表达式工具类,这里列举一些常用的工具类. Objects工具类 1 2 3 4 5 6 7 8 /* * 当obj不为空时,返回obj,否则返回default默认值 ...

  2. JavaSE-基础语法(二)-系统类(java.lang.*)和工具类(java.util.*)

    系统类(java.lang.*)和工具类(java.util.*) 一.系统类(java.lang.*) 这个包下包含java语言的核心类,如String.Math.System和Thread类等,使 ...

  3. vue项目工具文件utils.js javascript常用工具类,javascript常用工具类,util.js

    vue项目工具文件utils.js :https://blog.csdn.net/Ajaxguan/article/details/79924249 javascript常用工具类,util.js : ...

  4. 百度地图LV1.5实践项目开发工具类bmap.util.jsV1.0

    /** * 百度地图使用工具类-v1.5 * * @author boonya * @date 2013-7-7 * @address Chengdu,Sichuan,China * @email b ...

  5. 转载及总结:cron表达式详解,cron表达式写法,cron表达式例子

    cron表达式格式:{秒数} {分钟} {小时} {日期} {月份} {星期} {年份(可为空)}例  "0 0 12 ? * WED" 在每星期三下午12:00 执行(年份通常 ...

  6. 005-guava 集合-集合工具类-java.util.Collections中未包含的集合工具[Maps,Lists,Sets],Iterables、Multisets、Multimaps、Tables

    一.概述 工具类与特定集合接口的对应关系归纳如下: 集合接口 属于JDK还是Guava 对应的Guava工具类 Collection JDK Collections2:不要和java.util.Col ...

  7. cron表达式详解,cron表达式写法,cron表达式例子

    (cron = "* * * * * *") cron表达式格式:{秒数} {分钟} {小时} {日期} {月份} {星期} {年份(可为空)}例  "0 0 12 ? ...

  8. 百度地图LV1.5实践项目开发工具类bmap.util.jsV1.3

    /** * 百度地图使用工具类-v1.5 * * @author boonya * @date 2013-7-7 * @address Chengdu,Sichuan,China * @email b ...

  9. 百度地图LV1.5实践项目开发工具类bmap.util.jsV1.2

    /** * 百度地图使用工具类-v1.5 * * @author boonya * @date 2013-7-7 * @address Chengdu,Sichuan,China * @email b ...

  10. 百度地图LV1.5实践项目开发工具类bmap.util.jsV1.1

    /** * 百度地图使用工具类-v1.5 * * @author boonya * @date 2013-7-7 * @address Chengdu,Sichuan,China * @email b ...

随机推荐

  1. 国际认可!天翼云合规领域影响力up!

    近日,天翼云科技有限公司成功通过ISO 37301合规管理体系双认证(GB/T 35770-2022/ISO 37301:2021 & CTS GHMS001-2024),标志着公司合规管理和 ...

  2. .NET最佳实践:webapi返回IAsyncEnumerable提升性能

    什么是IAsyncEnumerable IAsyncEnumerable<T> 是 .NET 中用于表示异步数据流的接口. 它允许你逐个异步地获取数据项,而不是将所有数据一次性加载到内存中 ...

  3. Zabbix Agent 安装配置

    1 介绍 zabbix([`zæbiks])是一个基于WEB界面的提供分布式系统监视以及网络监视功能的企业级的开源解决方案.    zabbix能监视各种网络参数,保证服务器系统的安全运营:并提供灵活 ...

  4. Luogu P11628 WC2025 猫粮 题解 [ 绿 ] [ 贪心 ] [ adhoc ] [ 鸽巢原理 ]

    猫粮:WC 诈骗题.我竟然能切 WC 的 T3 也是逆天了. 话说切了猫粮能变成猫娘吗 qwq. 思路 首先题目里有下面几点关键的性质: 所有猫粮质量总和等于所有猫要吃的质量总和. 优质的有 \(n\ ...

  5. WPF .Net Core 3.1遇到Satellite Assemblies无法正常加载的处理

    1.原因 加载的时候没有调取 AssemblyLoadContext.Default 2.解决方案: 在程序启动的时候,手动调用 /// <summary> /// Interaction ...

  6. C# USB 摄像头 OpenCV 视频picBox呈现,抓拍图像保存呈现。没有注释版本。

    1.winform 应用程序,两个picturebox空间,一个用于视频呈现,一个用于抓拍呈现. 2.引用包OpenCvSharp4.OpenCvSharp4.Extensions.OpenCvSha ...

  7. 【Jmatpro 10.0】根据材料牌号输出应力-应变曲线

    1.前提条件 Jmatpro 软件 一个材料牌号或者材料成分数据 2. 步骤 以 X15Cr 13牌号金属为案例 材料数据来自:材数库 运行jmatpro软件 选择 material type:sta ...

  8. 扩展知识:vscode配置easyx

    扩展知识:vscode配置easyx 前言 ‍ 因为个人用习惯了vscode,对于visual studio的操作只能说相当程度上很不适应,因此,我打算经历一番配置,让vscode可以配置上easyx ...

  9. go 遍历修改切片数据

    package main import "fmt" type good struct { id int64 sum int64 } func main() { good1 := g ...

  10. nginx + lua脚本

    Nginx配合Lua 案例 今天实现一个非常简单的例子. 云服务器上部署的了一个很通用的应用程序(它没有保护策略),其端口是a,但是我想使用他,就要通过公网ip:端口去访问它.暴露在外面很不安全. 那 ...