这是我参与更文挑战的第 7 天,活动详情查看:更文挑战
写在前面:工作中需要做一个定时任务的功能。经过讨论之后,确定使用 quartz 来实现任务调度,后端接收和返回的都是一个 cron 表达式,而前端需要有一个友好的界面来协助用户输入正常的 cron 并校验合法性。
这就是写这篇文章的原因。
了解 cron 表达式
cron 表达式是用来进行定时任务调度的计算机可读的字符串。不同的程序支持的 cron 表达式规则和对 cron 表达式解析器的实现均有所不同。
以 quartz 中的 cron 表达式为例,表达式的格式具有七个字段:
| 字段名 | 允许的值 | 允许的特殊字符 |
|---|---|---|
| 秒 | 0-59 | , - * / |
| 分 | 0-59 | , - * / |
| 小时 | 0-23 | , - * / |
| 日 | 1-31 | , - * ? / L W C |
| 月 | 1-12 or JAN-DEC | , - * / |
| 周几 | 1-7 or SUN-SAT | , - * ? / L C # |
| 年 (可选字段) | empty, 1970-2099 | , - * / |
“周几”那个字段有些特别,不论是 0 还是 7,都代表周日。
除这些固定字符外,每个位置还支持一些辅助字符。具体如下:
“/”:表示从几开始,每隔固定时间执行一次。比如说:
- 在分钟字段下的值是
0/25,指从第 0 分钟开始,每 25 分钟执行一次 - 在分钟字段下的值是
3/4,指从第 3 分钟开始,每 4 分钟执行一次
这里有一个点要注意:cron 表达式不会记录上次执行的时间,因此上面的 0/25 的执行时间为
0:0, 0:25, 0:50, 1:0, 1:25, 1:50,而不是从当前时间向后推 25 分钟执行。这可能和你印象中的执行时间不大一样。
“?”:表示每月的某一天,或第几周的某一天。表示不确定的值
“L”:用于每月,或每周,表示为每月的最后一天,或每个月的最后星期几如“6L”表示“每月的最后一个星期五”
“W”:表示为最近工作日(周一到周五,国外没有调休),如“15W”放在每月(day-of-month)字段上表示为“到本月15日最近的工作日”
“#”:是用来指定该月第几个周 X。比如说:
- 在每周字段下的值是
6#3, 则表示“每月第三个星期五”
“,”字符:指定数个值,每个值之间用逗号分隔。
“-”字符:指定一个值的范围,比如说:
- 分钟下
0-5,指从第 0 分钟到第 5 分钟。 执行时间为:0, 1, 2, 3, 4, 5
“L”字符:用在日表示一个月中的最后一天,用在周表示该月最后一个星期 X
上述即为 cron 表达式的部分规则。为简洁起见,有些样例没有完全展示
cron 表达式推断之后任务执行的时间
因此根据上面提到的规则,可以实现一个迭代器,用来生成后续任务执行的时间。具体方式可以参考 www.npmjs.com/package/cro… 。
后续将会将代码分析更新在此处,敬请期待
cron 表达式反解析及生成
有一些前端插件可以做到这项功能。比如说 github.com/jingjingke/… 。作者的代码注释和文档都很清晰,虽然好像没啥人用,但同样值得去看一下。
后续将会将代码分析更新在此处,敬请期待