云计算百科
云计算领域专业知识百科平台

Cron 表达式进阶:特殊字符 L/W/# 实战

0 0 0 L * ? 是什么意思?15W 和 5#3 又代表什么?这三个高级特殊字符让 Cron 表达式能描述"月末执行"“最近工作日执行”"第三个周五执行"这类复杂调度。本文用实际案例讲透它们的用法。

为什么需要 L/W/#

基础的特殊字符 * , – / 能覆盖大部分定时任务,但有些场景搞不定:

  • 每月最后一天执行——1 月 31 号、2 月 28 号(闰年 29 号)、4 月 30 号,天数不固定,/ 步长和数字列表都写不了
  • 每月 15 号最近的工作日执行——如果 15 号是周六,应该提前到 13 号周五执行
  • 每月第三个周五执行——5 只表示每周五,没法指定第几周

这三个需求分别对应 L、W、# 三个特殊字符。它们只支持 Quartz Cron(6 段格式),标准 Unix Cron(5 段)不支持。

L — 最后

L 是 Last 的缩写,表示"最后一个"。用在日字段表示当月最后一天,用在周字段表示当月最后一个周几。

日字段的 L

0 0 0 L * ? 每月最后一天 0 点执行
0 0 3 L * ? 每月最后一天 3 点执行

1 月 L = 31 号,2 月 L = 28 号(闰年 29 号),4 月 L = 30 号。自动适配每月天数,不用手动维护。

周字段的 L

0 0 0 ? * 5L 每月最后一个周五执行
0 0 0 ? * 1L 每月最后一个周一执行

5L 表示当月最后一个周五。数字在前,L 在后,表示"最后一个周 X"。

L 的组合

0 0 0 L-3 * ? 每月倒数第 3 天执行

L-3 表示从月末往前推 3 天。1 月 L-3 = 28 号,2 月 L-3 = 25 号(非闰年)。这个语法较新,不是所有实现都支持。

W — 最近工作日

W 是 Weekday 的缩写,表示"最近的工作日"(周一到周五)。只用在日字段。

0 0 0 15W * ? 每月 15 号最近的工作日执行

15W 的规则:

  • 如果 15 号是工作日(周一到周五),就在 15 号执行
  • 如果 15 号是周六,提前到 14 号周五执行
  • 如果 15 号是周日,推迟到 16 号周一执行

注意 W 只能向前找工作日,不会跨月。如果 1 号是周六,1W 会在 1 号执行吗?不会——1W 找不到前面的工作日,会在 1 号执行(即使它是周六),因为不能跨到上个月。

0 0 0 1W * ? 每月 1 号最近的工作日执行
0 9 0 LW * ? 每月最后一个工作日 9 点执行

LW 组合表示当月最后一个工作日,适合月度结算场景——永远是当月最后一个工作日,不会在周末执行。

# — 第几周

# 表示"第几周的周几",只用在周字段。格式为 周几#第几周。

0 0 0 ? * 5#3 每月第三个周五执行
0 0 0 ? * 1#1 每月第一个周一执行
0 0 0 ? * 0#2 每月第二个周日执行

5#3 中的 5 表示周五,3 表示第 3 周。注意"第几周"是从该月第一个对应的周几开始算,不是日历周。

如果指定的周数超出了当月的实际周数(比如 5#5 表示第五个周五,但某月只有四个周五),该月不会执行,不会报错。

? 的互斥规则

? 表示"不指定",只能用在日字段或周字段,且这两个字段不能同时为 *。

为什么?因为日和周有逻辑冲突。0 0 0 * * ? 表示每天执行,周字段用 ? 表示"日已经说了每天,周不限制"。如果写成 0 0 0 * * *,引擎无法判断"每天"和"每周每天"是否矛盾。

0 0 0 * * ? 日字段 *,周字段 ? → 每天
0 0 0 ? * MON 日字段 ?,周字段 MON → 每周一
0 0 0 15 * ? 日字段 15,周字段 ? → 每月 15 号
0 0 0 15W * ? 日字段 15W,周字段 ? → 每月 15 号最近工作日
0 0 0 ? * 5#3 日字段 ?,周字段 5#3 → 每月第三个周五

规则很简单:日字段指定了具体值,周字段就用 ?;周字段指定了具体值,日字段就用 ?。两者不能同时为 *。

完整案例对照表

场景表达式中文含义
每月最后一天凌晨执行 0 0 0 L * ? 当月最后一天 0 点
每月最后一天 23 点执行 0 0 23 L * ? 当月最后一天 23 点
每月最后一个工作日执行 0 0 0 LW * ? 当月最后一个工作日 0 点
每月 15 号最近工作日 0 0 0 15W * ? 当月 15 号最近工作日 0 点
每月最后一个周五 0 0 0 ? * 5L 当月最后一个周五 0 点
每月第三个周五 0 0 0 ? * 5#3 当月第三个周五 0 点
每月第一个周一 0 0 0 ? * 1#1 当月第一个周一 0 点
每月倒数第三天 0 0 0 L-3 * ? 当月倒数第 3 天 0 点

在线验证

L、W、# 这三个特殊字符的语义比较抽象,光看文档很难确认写对没有。可以在 盘子工具站 Cron 表达式工具 在这里插入图片描述 上验证这些表达式——输入 0 0 0 15W * ? 后,中文解释会显示"每月 15 号最近的工作日执行",触发时间预览会列出接下来几个月的实际触发日期,你可以看到 15 号是周六时是否确实提前到了 13 号周五。切换到 5 段模式时工具会提示不支持 L/W/#,帮助你理解为什么这些字符只在 6 段格式中可用。 在这里插入图片描述 在这里插入图片描述

把上面的完整案例对照表里的表达式依次粘贴进工具,对照中文解释和触发时间预览,确认每个表达式都符合你的预期。特别是 5#3(第三个周五)和 LW(最后一个工作日),通过触发时间预览观察跨月变化,理解最直观。

赞(0)
未经允许不得转载:网硕互联帮助中心 » Cron 表达式进阶:特殊字符 L/W/# 实战
分享到: 更多 (0)

评论 抢沙发

评论前必须登录!