java_cron表达式_打印下次执行时间验证表达式是否正确

java_cron表达式_打印下次执行时间验证表达式是否正确

前言

cron表达式不常用,基本写好了很少去修改。不过在写的过程中会遇到一个问题,就是这个表达式对不对?我们怎么去验证,测试时不能等待这个任务去执行吧!
如果按分钟、按秒的调度还好说,等等可以。如果按日、月、周为周期的怎么等?
下面介绍如何通过CronTrigger类打印cron表达式的下次执行时间,验证cron表达式的方法。

环境

  • JDD 1.8

cron表达式格式

Cron 表达式是一个具有时间含义的字符串,分为 6 或 7 个域,每个域用空格分隔,一个域代表一种含义。
Cron 有如下两种语法格式:

  • 秒 分 时 日 月 周
  • 秒 分 时 日 月 周 年

cron各域字符含义及可选值

  • 取值范围

    • 秒 [0, 59]
    • 分 [0, 59]
    • 时 [0, 23]
    • 日 [1, 31]
    • 月 [1, 12]
    • 周 [1, 7] 其中 1 表示星期一,7 表示星期日。
    • 年 留空,1970~2099
  • 特殊字符

    • 秒 * , - /
    • 分 * , - /
    • 时 * , - /
    • 日 * , - / ? L W C
    • 月 * , - /
    • 周 * , - / ? L C #
    • 年 , - * /
  • 特殊字符含义

    • 字符:* 表示所有可能的值。如:在月份域中,* 表示每个月;在星期域中,* 表示星期的每一天。
    • 字符:, 表示枚举值。如:在分钟域中,5,20 表示分别在 5 分钟和 20 分钟触发一次。
    • 字符:- 表示范围 。如:在分钟域中,5-20 表示从 5 分钟到 20 分钟之间每隔一分钟触发一次。
    • 字符:/ 表示步长 。如:在分钟域中,0/15 表示从第 0 分钟开始,每 15 分钟触发一次。在分钟域中3/20表示从第 3 分钟开始,每 20 分钟触发一次。
    • 字符:? 表示不指定值,仅日期和星期域支持该字符 。如:当日期或星期域其中之一被指定了值以后,为了避免冲突,需要将另一个域的值设为?。
    • 字符:L 表示单词 Last 的首字母,即最后一天,仅日期和星期域支持该字符 。如:在日期域中,L 表示某个月的最后一天。在星期域中,L 表示一个星期的最后一天,也就是星期日(SUN)。如果在 L 前有具体的内容,例如,在星期域中的 6L,表示这个月的最后一个星期六。
    • 字符:W 表示有效工作日(周一到周五),只能出现在日期域,系统将在离指定日期最近的有效工作日触发事件。W 字符寻找当前月份中最近有效工作日,连用字符 LW 时表示为指定月份的最后一个工作日。
    • 字符:# 表示 。如:确定每个月第几个星期几,仅星期域支持该字符。
    • 字符:C 表示 。如:这个字符依靠一个指定的“日历”。也就是说这个表达式的值依赖于相关的“日历”的计算结果,如果没有“日历”关联,则等价于所有包含的“日历”。仅日期和星期域支持该字符。

Cron表达式示例

  • 0 15 10 ? * *
    • 每天上午 10:15 执行任务
  • 0 15 10 * * ?
    • 每天上午 10:15 执行任务
  • 0 0 12 * * ?
    • 每天中午 12:00 执行任务
  • 0 0 10,14,16 * * ?
    • 每天上午 10:00 点、下午 14:00 以及下午 16:00 执行任务
  • 0 0/30 9-17 * * ?
    • 每天上午 09:00 到下午 17:00 时间段内每隔半小时执行任务
  • 0 * 14 * * ?
    • 每天下午 14:00 到下午 14:59 时间段内每隔 1 分钟执行任务
  • 0 0-5 14 * * ?
    • 每天下午 14:00 到下午 14:05 时间段内每隔 1 分钟执行任务
  • 0 0/5 14 * * ?
    • 每天下午 14:00 到下午 14:55 时间段内每隔 5 分钟执行任务
  • 0 0/5 14,18 * * ?
    • 每天下午 14:00 到下午 14:55、下午 18:00 到下午 18:55 时间段内每隔 5 分钟执行任务
  • 0 0 12 ? * WED
    • 每个星期三中午 12:00 执行任务
  • 0 15 10 15 * ?
    • 每月 15 日上午 10:15 执行任务
  • 0 15 10 L * ?
    • 每月最后一日上午 10:15 执行任务
  • 0 15 10 ? * 6L
    • 每月最后一个星期六上午 10:15 执行任务
  • 0 15 10 ? * 6#3
    • 每月第三个星期六上午 10:15 执行任务
  • 0 10,44 14 ? 3 WED
    • 每年 3 月的每个星期三下午 14:10 和 14:44 执行任务

测试方法


import org.junit.Test;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.scheduling.support.SimpleTriggerContext;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Date;

public class CronTest {

    /*
    取值范围:
        秒   [0, 59]
        分   [0, 59]
        时   [0, 59]
        日   [1, 31]
        月   [1, 12]
        周   [1, 7]
    * */
    /** cron表达式验证,打印下次执行时间 */
    @Test
    public void nextCronTrigger(){
        String cron_s = "0/2 * * * * ? ";
        String cron_min = "0 0/2 * * * ?";
        String cron_h = "0 0 0/2 * * ?";
        String cron_d = "0 1 1 1/1 * ?";
        String cron_w = "0 1 1 * * 2";
        String cron_month = "0 1 1 1 1/1 ?";
        String cur = format(new Date());
        System.out.println("现\t"+cur);
        System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
        printNextExeTime("秒",cron_s);
        printNextExeTime("分",cron_min);
        printNextExeTime("时",cron_h);
        printNextExeTime("日",cron_d);
        printNextExeTime("周",cron_w);
        printNextExeTime("月",cron_month);
    }

    /** 打印下执行时间 */
    public void printNextExeTime(String msg,String cron){
        SimpleTriggerContext cxt = new SimpleTriggerContext();
        CronTrigger cronTrigger = new CronTrigger(cron);
        Date nextTime = cronTrigger.nextExecutionTime(cxt);
        String nextTimeStr = format(nextTime);
        System.out.println(msg+"\t"+nextTimeStr+"\t"+cron);
    }
    public String format(Date date){
        ZoneId zoneId = ZoneId.systemDefault();
        LocalDateTime localDate = date.toInstant().atZone(zoneId).toLocalDateTime();
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        return dateTimeFormatter.format(localDate);
    }
}

执行结果:

现	2023-11-14 14:24:01
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
秒	2023-11-14 14:24:02	0/2 * * * * ? 
分	2023-11-14 14:26:00	0 0/2 * * * ?
时	2023-11-14 16:00:00	0 0 0/2 * * ?
日	2023-11-15 01:01:00	0 1 1 1/1 * ?
周	2023-11-21 01:01:00	0 1 1 * * 2
月	2023-12-01 01:01:00	0 1 1 1 1/1 ?

Process finished with exit code 0

总结

通过上面的测试,可以方便的查看下次执行时间,去校验cron表达式是否正确。
需要注意的是 * 的使用,如写成这种形式 * */2 * * * ? 可能导致每秒钟都在执行。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Cron表达式是一种用于指定定时任务执行时间的字符串表达式。它由6个字段组成,分别表示秒、分、小时、天、月、周,每个字段都有一些特定的取值范围和取值规则。 以下是Cron表达式的格式: ``` <秒> <分> <小时> <日> <月> <周> <年> ``` 其中,年是可选的,其它字段都是必须的。以下是各个字段的取值范围和取值规则: - 秒 (0-59) - 分 (0-59) - 小时 (0-23) - 日 (1-31) - 月 (1-12) - 周 (0-7,0和7都表示周日) 在Cron表达式中,每个字段都可以是一个具体的数字,也可以是一个范围、一个列表或者一个通配符。以下是一些例子: - *:表示所有可能的值,比如“*”在分钟字段中表示每分钟都执行。 - ?:表示未指定,比如在日字段中表示不关心是几号。 - -:表示范围,比如在小时字段中表示10点到12点。 - /:表示间隔,比如在秒字段中表示每隔5秒执行一次。 - ,:表示列表,比如在周字段中表示周一和周二。 验证Cron表达式的方法有很多种,下面是一种Java实现的示例: ```java import org.quartz.CronExpression; public class CronUtils { public static boolean isValid(String cronExpression) { try { new CronExpression(cronExpression); return true; } catch (Exception e) { return false; } } } ``` 这个示例使用了Quartz框架提供的CronExpression类来解析和验证Cron表达式。如果传入的表达式格式不正确,会抛出异常并返回false,否则返回true。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值