quartz cron 表达式用法(CronTrigger 教程)

原文链接:http://www.quartz-scheduler.org/documentation/quartz-1.x/tutorials/crontrigger

介绍

cron 是一个 UNIX 工具,它已经存在了很长的时间,时间证明了它的调度能力很强大。CronTrigger class 是基于 cron 的调度功能。

CronTrigger 使用了 “cron 表达式”,可以创建一个 cron 表达式来触发调度任务,例如:“每个星期一到星期五的上午 8 点”或者是“每个月的最后一个星期五的下午 1:30”。

cron 表达式非常强大,但有时候很难理解。本教程的目的就是解开创建 cron 表达式的谜题,给大家一个资源可查,省得去论坛或邮件列表中问其他人。

格式

cron 表达式是由 6 或 7 位由空格分开的字段组成的。各个字段可以包含任何被允许的值,伴随着对应某个字段所允许的特殊字符的各种组合。各个字段如下:

字段名称强制出现允许的值允许的特殊字符
0-59,-*/
0-59,-*/
0-23,-*/
日期1-31,-*?/LW
1-12或者是 JAN-DEC,-*/
星期1-7或者是 SUN-SAT,-*?/L#
空或者是1970-2099,-*/

很简单的 cron 表达式:* * * * ? *
很复杂的,例如:0/5 14,18,3-39,52 * ? JAN,MAR,SEP MON-FRI 2002-2010

特殊字符

  • *(“所有的值”)-匹配某个字段内的所有的值。例如,在“分”字段中的“*”代表“每一分钟”。

  • ?(“没有特定的值”)-“?”只能用在“日期”和“星期”字段中,在其他字段中是不能用的。例如,我想要触发器在某个月的某一天(比如是 10 号)触发,但我不关注那天是星期几,我就可以把 “10” 放到“日期”字段中,把“?”放到“星期”字段中。结合下面的例子来清楚的说明 cron 表达式的使用方法。

  • - -用来定义范围。例如,在时字段中的“10-12”意思是“10 点, 11 点和 12 点”。

  • ,-用来定义追加的值(列表)。例如,在星期字段中的“MON,WED,FRI”意思是“星期一,星期三,星期五”。

  • /-用来定义增量。例如,在秒字段中的“0/15”表示从0秒开始每隔15秒,就是“0 秒,15 秒,30 秒,45 秒,0 秒,15 秒……”。在分字段中的“5/15”表示从 5 分开始每隔 15 分,就是“5分,20分,35分,50分,5 分, 20分……”。也可以在”空字符之后定义/,例如/5等价于在/前面有个0,即/5 等价于 0/5 。在日期字段中的“1/3”的意思是“在某月的第 1 天开始每隔 3 天触发一次”。

  • L(“last”)-只允许在两个字段中出现 “L” ,但 “L” 在这两个字段中每处的含义却各不相同。例如,在日期字段中的 “L” 意思是月末,即一个月的最后一天- 1 月的 31,平年 2 月的 28。如果 “L” 出现在星期字段中,则表示 “7” 或 “SAT”,即星期六(在西方星期六是一周的最后一天)。但是在星期字段中的 “L” 出现在一个数字之后意思是“某个月的最后一个星期几”-例如“6L”意思是“某个月的最后一个星期五”。在使用“L”选项的时候最好不要再用列表、范围值,否则的话会得到令人迷惑的结果。

  • W(“weekday 工作日”)-用来定义距离给定某一天最近的一个工作日(星期一到星期五)。例如,在日期字段中定义了 “15W” 意思是“某个月中距离 15 号最近的一个工作日”。
    如果 15 号是星期六的话,触发器会在星期五即 14 号触发。如果 15 号是周日,触发器会在下周一即 16 号触发。如果 15 号是星期二的话,触发器会在星期二当天 15 号触发。然而,如果在日期字段中定义了
    “1W”,如果 1 号是星期六的话,触发器会在下个星期一即 3 号触发,它不会跳回到上个月去触发。“W” 只能定义在日期中字段中,并且在日期字段中只能定义单独的一天,不能定义一个范围或一个日期列表。

    “L” 和 “W” 还可以组合出现在日期字段中,即“LW”,表示“某个月的最后一个工作日”。

  • #-用来定义“某个月的第 n 个星期几”,# 只允许出现在星期字段中。例如,在星期字段中的“6#3”表示“某个月的第 3 个星期 5”(6 表示星期 5 ,3 表示某个月的第 3 周)。另一个例子:“2#1”意思是“某个月的第一个周的星期一 ”。
    “4#5”意思是“某个月中第 5 周的星期三 ”。注意,# 后面只允许出现 1-5(一般来说一个月中最多只有 5 周,不知道有没有可能有 6 周)。如果定义“#5”,在某个月中的第五周没有五个工作日中的任何一天,那么触发器在当月就不会触发。补充:我在我本地试了下,在星期字段中定义
    “#5” 会报错,# 之前必须要有数字,不知道是因为我的版本低还是我误解了原文的意思,或者是原文中的“#5”意思是“1#5”、“2#5”、“3#5”、“4#5”、“5#5”、“6#5”、“7#5”中的一种,原文偷懒了下。

    月份和星期的英文单词是不区分大小写的。MON 和 mon 的含义是一样的,都表示是星期一 。

例子

下面是一些完整的例子:

表达式含义
0 0 12 * * ?每天中午 12:00整触发
0 15 10 ? * *每个月的星期一到星期七的上午 10:15 分触发,其实就是每天的上午 10:15,它和 0 15 10 * * ? 是等价的
0 15 10 * * ?每天上午 10:15 分触发
0 15 10 * * ? *每天上午 10:15 分触发
0 15 10 * * ? 20052015 年的每天上午 10:15 分触发
0 * 14 * * ?每天下午 2 点开始每隔 1 分钟触发一次,一直到下午 2:59 分之后结束。
0 0/5 14 * * ?每天下午 2 点开始每隔 5 分钟触发一次,一直到下午 2:55 分之后结束。
0 0/5 14,18 * * ?每天下午 2 点开始每隔 5 分钟触发一次,一直到下午 2:55 分之后结束。然后,每天下午 6 点开始每隔 5 分钟触发一次,一直到下午 6:55 分之后结束。
0 0-5 14 * * ?每天下午 2 点开始每隔 1 分钟触发一次,一直到下午 2:05 分之后结束。
0 10,44 14 ? 3 WED三月份的每个星期三下午 2:10 分和下午 2:44 分各触发一次。
0 15 10 ? * MON-FRI每个星期一、星期二、星期三、星期四、星期五的上午 10:15 分触发。
0 15 10 15 * ?每月的 15 号上午 10:15 分触发一次。
0 15 10 L * ?每月的最后一天的上午 10:15 分触发一次。
0 15 10 ? * 6L每月的最后一个星期五的上午 10:15 分触发一次。
0 15 10 ? * 6L 2002-20052002-2005 年的每月的最后一个星期五的上午 10:15 分触发一次。
0 15 10 ? * 6#3每月的第 3 周的星期五的上午 10:15 分触发一次。
0 11 11 11 11 ?每年的 11 月 11 日上午 11:11 分触发一次。

注意日期和星期字段中的“*”和“?”的作用。
补充:日期和星期字段中不能同时出现 “?”,为什么呢?一个定时器最终必须落实到某一天的某时某分某秒,其中日期和星期都可以表示某一天,但其他字段却不能表示某一天,所以这两个字段必须指定一个字段,两个字段中都是“?”则无法指定是哪一天,所以语法上是不正确的。

注意

  • 暂时还不支持同时定义日期字段和星期字段(换句话说,日期字段和星期字段中必须有一者为“?”,但不能同时为“?”)。
  • 在晚上 12:00 到 1:00 之间设置触发时间应该注意-“夏令时”会引起跳过或重复触发,具体是跳过触发还是触发取决于时间是往快拨还是往慢拨。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
要获取QuartzJobBean子类的cron表达式,可以通过以下步骤: 1. 在子类中添加一个成员变量,用于存储cron表达式,例如: ```java private String cronExpression; ``` 2. 在子类中添加一个setter方法,用于设置cron表达式: ```java public void setCronExpression(String cronExpression) { this.cronExpression = cronExpression; } ``` 3. 在子类中重写QuartzJobBean的executeInternal方法,在这个方法中可以使用成员变量cronExpression获取cron表达式: ```java @Override protected void executeInternal(JobExecutionContext context) throws JobExecutionException { // 获取当前时间 Date now = new Date(); // 根据cron表达式计算下一次触发时间 CronTrigger trigger = TriggerBuilder.newTrigger() .withIdentity("trigger", "group") .withSchedule(CronScheduleBuilder.cronSchedule(cronExpression)) .build(); Date nextFireTime = trigger.getFireTimeAfter(now); // 输出下一次触发时间 System.out.println("Next fire time: " + nextFireTime); } ``` 4. 在调用子类的setter方法设置cron表达式后,可以使用Quartz的Scheduler来启动任务: ```java // 创建一个JobDetail实例,指定子类为Job实现类 JobDetail jobDetail = JobBuilder.newJob(MyJob.class).build(); // 创建一个Trigger实例,指定cron表达式 Trigger trigger = TriggerBuilder.newTrigger() .withIdentity("trigger", "group") .withSchedule(CronScheduleBuilder.cronSchedule(myJob.getCronExpression())) .build(); // 启动任务调度器 SchedulerFactory schedulerFactory = new StdSchedulerFactory(); Scheduler scheduler = schedulerFactory.getScheduler(); scheduler.start(); // 将JobDetail和Trigger注册到任务调度器中 scheduler.scheduleJob(jobDetail, trigger); ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值