cron表达式

      cron表达式主要应用于quartz中,在linux中也有用到,主要功能是设置一个定时器,当到达特定时间时触发任务。

      cron表达式主要由七个部分组成,这七个部分分别是秒、分、时、日、月、周、年,每个部分之间由空格分离,顺序必须按照以上顺序,其中年可以省略不写。如:

10 12 9 24 11 ?   //表示每年的11月24日9点12分10秒
10 12 9 24 11 ?2012   //表示2012年的11月24日9点12分10秒

下面具体来看每个部分能够取的值:

其中月的允许值也可以为月份的英文简写,如JAN, FEB…DEC;

日表示每月的第几天,也就是几号;

周表示星期几,1表示星期天,2表示星期一,7表示星期六,也可以用英文简写,如SUN, SAT...

 

特殊字符解释:

* 表示这个部分的所有合法值,如秒上的*表示每一秒,分上的*表示每一分;

, 用来指定一个值列表,如只想在每分钟10秒,13秒和21秒这三个时间点上触发,则用:

10,13,20  *  *  *  *  ?

如果只想在每天的7点,11点和20点0分0秒触发,则用:

0  0  7,11,20  *  *  ?

 

- 用于指定一个范围,例如在每天的14点在20点之间(包括14和20)每个整点0分0秒都触发一次,可以用:

0  0  14-20  *  *  ?

 

/ 用来指定一个递增的时间,例如要在每隔月3号0点0分0秒开始(包括3号),每隔5天触发一次(3,8,13…),则用:

0  0  0  3/5  *  ?

也就是说, /左边的数字表示起始值,右边的数字表示步长

如果想要在每月2号0点0分0秒号到11号0点0分0秒范围内每隔3天触发一次,则用:

0  0  0  2-11/3  *  ?

 

这个字符只能用在日或者周这两个部分上,表示忽略这个部分的值。之所以要用到这个字符,是因为有时日和周这个两个部分是冲突的,例如下面的cron表示式:

 

0  0  0  11  *  4

表示每个月的11号星期四0点0分0秒这一天触发。但是,一个月的11号也可能不是星期四。所以当我们制定了日或者周这两者之中的一个时,另一个就不用管另外一个的值了,直接用?来忽略它。

例如每个月的13号0点0分0秒触发,则用:

0  0  0  13  *  ?

要注意的是,一般如果日或者周其中之一有值的话,另一个就取?;如果这两者都是取所有值*(如每天的16点0分0秒触发),则一般把周设为?,把日设为*:

 

0  0  16  *  *  ?

 

L 只能用在日和周这两个部分上。当用在日上是,表示每个月的最后一天,如8月的最后一天为31号,9月最后一天为30号;

如每个月最后一天的14点29分56秒触发:

56  29  14  L  *  ?

如果L用在周上,表示每个月最后一周的星期几,如5L表示每个月最后一个周的星期四;

例如每个月最后一周的星期三0点0分0秒触发:

0  0  0  ?  *  4L

 

W 表示工作日(即星期一到星期五),只能用在日上,用来指定每个月离特定日最近的一个工作日,如12L,表示当月内离12号最近的一个工作日触发,如果当天就是工作日,则当天就触发。注意不能跨月,最近的工作日必须和指定的那天是同一个月内的。假设取离31号最近的工作日(31W),同时31号为星期天;这时只能取该月的29号(星期五),而不能取下一个月的1号。

 

# 只能用在周上,表示月份中的第几周的星期几。如5#2表示第2周的星期四,也就是第二个周四。

如九月份的第三个周五14点29分37秒触发:

37  29  14  ?  9  6#3

 

注意点(个人看法,不知道对错):

在某些情况下,cron表达式只是用来限制触发的时间范围(也即只能在这个时间范围内触发),而不是设置触发时间的起始点。

例如:

如果我们想要在12月18号0点0分0秒触发,以后每隔三天触发一次,开始时可能会这样写:

0  0  0  18/3  12  ?

但是实际结果却并不是想要的结果(我也不知道正确的表达式该怎么写)。

这个表达式实际限制了触发时间,也就是只能在每年的12月内触发,同时只能以12月18号为开始触发时间。

所以实际的触发时间是:

2015.12.18
2015.12.21
2015.12.24
2015.12.27
2015.12.30
2016.12.18
2016.12.21
….

之所以会跳转到2016年,是因为我们并没有限制年份,所以当2015年的12月走完后,就会跳到2016年的12月。

如果我们限定了年份为2015年:

0  0  0  18/3  12  ?  2015

那么触发时间为:

2015.12.18
2015.12.21
2015.12.24
2015.12.27
2015.12.30

之后就没有了,表示在2015年12月内,从12月18号开始,每隔三天触发一次。所以只能在2015年12月内触发。

其他情况也类似,如果其他部分也写了具体数值,则表示只能在那个时间内触发,如

0  0  2/5  18  12  ?  2015

表示在2015年12月18号内,从2点开始,每隔5个小时触发一次;过了2015年12月18号就不在触发了。

同时,cron表达式也无法支持多时间段,比如从9点30开始到11点30,和从13点到15点,每15分钟执行一次。

下面是一些从其他地方收集的cron表示式例子:

用法

表达式

每天的从 5:00 PM 至 5:59 PM 中的每分钟触发

0 * 17 * * ?

每天的从 11:00 PM 至 11:55 PM 中的每五分钟触发

0 0/5 23 * * ?

每天的从 3:00 至 3:55 PM 和 6:00 PM 至 6:55 PM 之中的每五分钟触发

0 0/5 15,18 * * ?

每天的从 5:00 AM 至 5:05 AM 中的每分钟触发

0 0-5 5 * * ?

每天的 3:00 AM 

0 0 3 * * ?

每天的 3:00 AM (另一种写法) 

0 0 3 ? * *

每天的 12:00 PM (中午)

0 0 12 * * ?

在 2005 中每天的 10:15 AM

0 15 10 * * ? 2005

在每个周一,二, 三和周四的 10:15 AM

0 15 10 ? * MON-FRI

每月15号的 10:15 AM  

0 15 10 15 * ?

每月最后一天的 10:15 AM

0 15 10 L * ?

每月最后一个周五的 10:15 AM 

0 15 10 ? * 6L

在 2002, 2003, 2004, 和 2005 年中的每月最后一个周五的 10:15 AM 

0 15 10 ? * 6L 2002-2005

每月第三个周五的 10:15 AM

0 15 10 ? * 6#3

每月从第一天算起每五天的 12:00 PM (中午)

0 0 12 1/5 * ?

每一个 11 月 11 号的 11:11 AM

0 11 11 11 11 ?

三月份每个周三的 2:10 PM 和 2:44 PM

0 10,44 14 ? 3 WED

<think>好的,我现在需要帮助用户了解如何编写和解析cron表达式。首先,根据用户提供的引用内容,我需要整理出关键。引用中提到了cron-validator和cron-parser用于验证和解析表达式,还有cron-utils库,以及Java中的CronExpression类。用户可能想知道如何手动编写cron表达式,以及如何用工具或库来解析它们。 首先,我需要解释cron表达式的基本结构。标准的cron表达式有五个或六个字段,分别代表分钟、小时、日期、月份、星期,和可选的年(在Quartz等扩展版本中)。例如,0 0 12 * * ? 表示每天中午12执行。需要举例说明每个字段的取值范围和特殊字符,比如星号、逗号、连字符、斜杠等。 接下来是编写部分。用户可能需要一些常见的例子,比如每分钟执行一次,每天凌晨执行,每周一执行等。这部分需要清晰明了,让用户能快速上手。 然后是解析部分。用户提到了Java中的CronExpression.getTimeAfter方法,这可能用于计算下次执行时间。需要介绍如何使用现有的库来解析cron表达式,例如在Java中使用cron-utils或Spring的CronSequenceGenerator,在Python中使用croniter,JavaScript中使用node-cron等。还要提到在线工具,如用户提到的bejson网站,方便用户快速验证表达式。 另外,用户提供的引用2提到了在开发中生成和解析cron表达式的需求,比如让用户界面设置时间生成表达式,或者解析表达式获取下一次执行时间。这部分需要强调库的重要性,避免手动解析的复杂性。 需要注意的是,确保回答中的LaTeX格式正确,行内公式用$...$,独立公式用$$...$$。例如,解释特殊字符时,如果有数学表达式,要用正确的格式。不过cron表达式本身不涉及数学公式,可能用代码块更合适,但根据系统指令,代码块需要用三个反引号包裹,并指定语言。 最后,生成相关问题需要考虑用户可能的后续疑问,比如验证工具、特殊字符的作用、不同语言的库推荐、如何获取下次执行时间,以及常见错误等。这些问题应该覆盖用户可能遇到的实际应用场景。 检查是否所有引用都正确标注,比如引用1提到cron-validator和cron-parser,引用2提到在线工具和cron-utils,引用3提到Java的getTimeAfter方法,引用4提到Java中解析表达式的代码示例。需要确保每个引用在回答中的引用标识正确对应。 总结回答结构:先解释cron的结构,然后编写示例,接着解析方法,最后推荐工具和库。相关问题部分需要覆盖编写、解析、工具、错误处理等方面的问题。</think>### 如何编写或解析 cron 表达式 #### 1. **编写 cron 表达式** cron 表达式由 **5-7个字段** 组成,分别表示时间单位和频率。标准格式为: ``` 秒(可选) 分 时 日 月 周 [年] ``` 其中 **年** 字段在部分工具(如Quartz)中支持。常用字段说明如下: | 字段 | 允许值 | 特殊字符 | 示例 | |------|-----------------|----------------|--------------| | 分 | 0-59 | `* , - /` | `0` 表示整 | | 时 | 0-23 | `* , - /` | `12` 表示中午12 | | 日 | 1-31 | `* , - / ? L` | `15` 表示每月15日 | | 月 | 1-12 或 JAN-DEC | `* , - /` | `*/3` 每3个月 | | 周 | 0-6 或 SUN-SAT | `* , - / ? L #`| `MON` 表示周一 | | 年 | 1970-2099 | `* , - /` | `2023` 仅2023年生效 | **特殊字符说明**: - `*`: 任意值 - `,`: 多个值(如 `1,3,5`) - `-`: 范围(如 `1-5`) - `/`: 步长(如 `0/15` 表示每15分钟) - `?`: 日或周字段的占位符(避免冲突) - `L`: 最后一天(如 `L` 表示月末) **常见示例**: - 每天中午12执行:`0 0 12 * * ?` [^3] - 每周一上午9:`0 0 9 ? * MON` - 每5分钟一次:`0 */5 * * * ?` --- #### 2. **解析 cron 表达式** 解析 cron 表达式主要用于 **获取执行计划**(如下次运行时间)或 **验证格式合法性**。常用方法如下: ##### 2.1 **使用工具库** - **Java**: - 通过 `CronExpression` 类解析: ```java CronExpression cron = new CronExpression("0 0 12 * * ?"); Date nextTime = cron.getTimeAfter(new Date()); // 计算下次执行时间 ``` - 使用 `cron-utils` 库生成或解析表达式[^2]。 - **Python**: - 使用 `croniter` 库: ```python from croniter import croniter iter = croniter("0 0 12 * * ?", datetime.now()) next_time = iter.get_next(datetime) ``` - **JavaScript**: - 使用 `node-cron` 或 `cron-parser`[^1]。 ##### 2.2 **在线工具** 通过网站(如 [bejson cron解析工具](https://www.bejson.com/othertools/cron/))直接输入表达式,自动生成执行时间表。 --- #### 3. **注意事项** 1. **字段冲突**:若同时指定 **日** 和 **周** 字段,可能触发未预期行为(如 `?` 用于占位符)。 2. **时区问题**:需明确表达式基于的时区(如服务器时区)。 3. **闰年处理**:部分工具可能不支持 `L` 在2月的特殊逻辑。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值