认识cron表达式
概要
这篇文章介绍了 cron 的含义、cron 表达式语法和应用场景。
什么是 cron
cron 读作 “克龙”,是一种时间单位,1cron 等于百万年。在计算机世界中,cron 被用作定时任务,即在指定时间、周期自动执行预置的任务。cron 表达式广泛用于各种定时任务、调度服务。
Cron表达式语法规则
cron 表达式是一个字符串,有七个域,分别是秒、分、时、日、月、周、年,域的值可以是数字、特殊字符或两者的结合,域之间以空格分隔。
域 | 含义 | 数字范围 | 可用字符 | 备注 |
---|---|---|---|---|
Seconds | 秒 | 0~59 | ,-*/ |
|
Minutes | 分 | 0~59 | ,-*/ |
|
Hours | 时 | 0~23 | ,-*/ |
|
Day of Month | 日 | 1~31 | ,-*/?LWC |
|
Month | 月 | 1~12 | ,-*/ |
值也可填 JAN-DEC |
Day of Week | 周(星期) | 1~7 | ,-*/?LC# |
也可填SUN-SAT,1 代表周日(SUN) |
Year | 年 | 1970~2099 | ,-*/ |
可选 |
注:
年
这个域是可选的,不限定年时,cron 表达式有 6 个域,分别是秒、分、时、日、月、周。
周
的取值范围在不同平台、不同语言中可能是不相同的,如在 linux 的 crontab 中,取值范围是0~7
,其中0
和7
都代表周日。
当域的值为数字时,表示在该时间时刻触发,如 0 0 8 * * ? *
表示在每天上午8点整触发。
特殊字符功能:
,
并列连接多个值,如1,3,4
表示在 1、3 和 4 时触发。-
表示范围,如1-3
表示从 1 到 3,包括 1、2、3。/
表示增量(步进),如0/5
表示从 0 开始,每增加 5 触发一次。*
表示所有值。?
用在日
(Day of Month)和周
(Day of Week)上,表示不限定值。日和周这两个域会相互影响,当指定了其中一个域,而另一个域不做限制时,另一个域要填?
。如想在每月 15 日早上 8 点整触发,不管是星期几都触发,则只能写成0 0 8 15 * ?
,周的值只能是?
,而不能是*
。个人理解:当指定了日为 15 后,如果同时指定周为*
,表示周天到周六每天都触发,将导致限定条件冲突,最终日的限定条件失效,因而必须指定周为?
表示只关注日不需要关注周。L
表示最后(Latest),只能用在日
或周
上,表示最后,如日
中单独使用L
表示月的最后一天,周
中单独使用L
表示一周的最后一天(SAT,周六);当L
与数字连用时,日中的3L
表示月的倒数第3天,周
的3L
表示本月的最后一个星期二。W
表示工作日(weekday),即周一到周五的任意一天,只能出现在日
中,将在离指定日期最近的有效工作日触发。如6W
表示将在距离 6 日最近的工作日触发,如果 6 日是工作日则在当日触发;如果 6 日是周六,则在周五触发;如果 6 日是周日,则在下周一触发。注意W
的最近寻找不会跨过月份。#
用于确定每个月的星期几,只能出现在周
中,如4#2
表示某月的第二个星期三。LW
可以连用,表示某月的最后一个工作日。C
表示和日历(Calendar)关联计算后的值,可用在日
或周
中,如日中的5C
表示某月 5日后的第一天;周中的5C
表示周四后的第一天。
示例
0 0 8 * * ? *
每天早上 8 点触发0/5 * * * * ?
每 5 秒触发一次0 30 9,17 * * ?
每天上午9点半和下午17点半触发0 0 2 L * ?
每月最后一日的2点整触发0 0 7-22 * * ?
每天上午7点到晚上22点的整点触发0 0 14 ? * TUES,THUR,SAT
周二、周四、周六的下午14点整触发0 0 10 ? 5 1#2
每年5月的第二个星期日(母亲节)的上午十点整触发0 30 16 LW * ?
每月最后一个工作日的下午16点半出发
使用场景
Java Spring 项目
在使用 Spring 框架开发的 Java 项目中,可以很方便的创建定时执行任务,并使用 cron 表达式来指定执行策略。如以下代码将每 5 秒打印一句 Hi
:
1 | import org.springframework.scheduling.annotation.EnableScheduling; |
代码说明:
@Component
注解用于将这个类标识为 Spring 组件,让 Spring 框架帮我们实例化和管理生命周期。@EnableScheduling
注解用于告诉 Spring 开启定时执行功能。@Scheduled(cron = "0/5 * * * * ?")
注解用于标识定时执行的方法,其中参数cron
指定使用 cron 表达式作为触发条件,这里的0/5 * * * * ?
表达式为 每 5 秒触发一次。
Java Cron 库
-
cron-utils: http://cron-parser.com/
一个用于解析、校验、迁移 cron 表达式的库。
-
Quartz Enterprise Job Scheduler: https://www.quartz-scheduler.org/
一个功能丰富且开源的企业级定时任务框架。
linux定时任务
在 linux 系统中,使用 crontab 来创建定时执行任务。
参考资料
- cron_百度百科: https://baike.baidu.com/item/cron/10952601
- crontab(5) - Linux manual page: https://man7.org/linux/man-pages/man5/crontab.5.html
- cron表达式详解,cron表达式写法,cron表达式例子: https://blog.csdn.net/sdujava2011/article/details/87343461/
总结
Cron 表达式用于创建定时器,表达式域包含 秒、分、时、日、月、周、年,域之间用空格分隔,一般年可省略。
要注意在不同平台、编程语言、定时任务框架中,Cron 表达式的规则可能不一样。