You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何编写适配DST变更、支持夏令时规则的通用CRON表达式

可行实现方案

前提说明

标准Linux原生cron不支持直接配置动态日期范围规则,以下分两种常用场景给出可落地的方案,所有方案默认将调度时区设置为America/New_York,自动适配EST/EDT切换,无需维护两套独立调度计划。

方案1:适用于支持高级CRON的调度框架(Quartz、Spring Scheduler等)

通过多条CRON规则组合实现需求,所有规则时区统一设为America/New_York:

  • 4月-10月全月每日18点触发:0 0 18 * 4-10 ?
  • 3月仅第二个周日及之后每日18点触发,拆分为两条规则:
    • 3月第二个周日当天触发:0 0 18 ? 3 SUN#2
    • 3月15日-31日每日18点触发:0 0 18 15-31 3 ?
  • 11月仅第一个周日之前的日期触发:0 0 18 1-6 11 ?

逻辑验证:3月第二个周日最晚为3月14日,因此15日之后的所有3月日期都符合范围;11月第一个周日最早为11月1日,最晚为11月7日,因此11月1-6日都符合范围,10月31日天然归属于4-10月的规则覆盖。

方案2:适用于Linux原生cron场景

通过「cron定时触发+脚本前置校验」的方式实现,步骤如下:

  1. 配置cron规则,每天18点触发执行脚本,时区设置为America/New_York:
0 18 * * * /path/to/your/script.sh
  1. 在你的业务脚本最开头加入以下判断逻辑,不符合时间范围直接退出:
# 获取当前日期的月份、当天日期
current_month=$(date +%m)
current_day=$(date +%d)
current_day=$((10#$current_day))

# 12-2月直接退出
if [ $((10#$current_month)) -ge 12 ] || [ $((10#$current_month)) -le 2 ]; then
    exit 0
fi

# 3月判断:是否已过第二个周日
if [ "$current_month" = "03" ]; then
    # 计算当年3月第二个周日的日期
    first_day_week=$(date -d "$(date +%Y)-03-01" +%w)
    first_sun_offset=$(( (7 - 10#$first_day_week) % 7 ))
    second_sun=$(( first_sun_offset + 8 ))
    if [ $current_day -lt $second_sun ]; then
        exit 0
    fi
fi

# 11月判断:是否早于第一个周日
if [ "$current_month" = "11" ]; then
    # 计算当年11月第一个周日的日期
    first_day_week=$(date -d "$(date +%Y)-11-01" +%w)
    first_sun=$(( 10#$first_day_week == 0 ? 1 : 7 - 10#$first_day_week + 1 ))
    if [ $current_day -ge $first_sun ]; then
        exit 0
    fi
fi

# 下方写入实际业务执行逻辑

内容的提问来源于stack exchange,提问作者Abhinav

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 17:06:03