全部指南
开发者

上午9点的Cron:时区与夏令时

上午9点的工作、时钟变更,以及部署前值得检查的三个时间戳。

一个工作日任务整个冬天都在上午 9 点运行。切换夏令时后,却变成了上午 10 点。Cron 表达式可能没有写错:调度服务按 UTC 执行,而你想要的是当地时间。

把排程复制到服务里之前,先确定它该按哪个时区运行。发给墨尔本团队的每日报告,和每小时执行一次的备份,不一定适合用同一套规则。

时区不包含在表达式里

这个五字段表达式表示周一至周五的 09:00:

0 9 * * MON-FRI

但它没有说明是哪里的 09:00。时区由调度服务决定。在 CozyToolkit 的 cron 构建器里切换时区,只会改变预览结果,不会把时区写进你复制的表达式。

如果部署平台支持按地区设置时区,可以选择 Australia/Melbourne。UTC+10 这样的固定偏移量不会随墨尔本的夏令时调整。

看看夏令时前后的三次运行

我们把时区设为 Australia/Melbourne,从 2026 年 10 月 2 日零点开始预览。接下来的三个工作日,运行时间如下:

墨尔本时间 UTC 时间
10 月 2 日星期五,09:00(UTC+10) 10 月 1 日星期四,23:00
10 月 5 日星期一,09:00(UTC+11) 10 月 4 日星期日,22:00
10 月 6 日星期二,09:00(UTC+11) 10 月 5 日星期一,22:00

当地时间始终是上午 9 点,对应的 UTC 时间却变了。如果把预览时区改为 UTC,同一条表达式就会在工作日的 UTC 09:00 执行,换算成墨尔本时间是周五 19:00、周一 20:00。

你可以下载排程和两组时间戳自行对照。文件使用 ISO 时间戳,末尾的 Z 表示 UTC。

在工具里重现这个结果

  1. 打开 cron 构建器,选择 粘贴表达式。
  2. 把上面的内容粘贴到 Cron 表达式。
  3. 将 计划时区 设为 Australia/Melbourne。
  4. 将 预览后 设为 2026 年 10 月 2 日 00:00。这里的日期和时间按你选定的时区解释。
  5. 查看 即将运行。在手机上,切换到对应的运行预览标签页。
  6. 切换到 UTC 做对比,同时留意预览起始日期:时区改变后,日期控件会显示同一时刻在新时区下的时间。

这个工具只预览运行日期,不会替你创建或执行定时任务。实际部署时,还要在调度服务里设置时区。

如果调度服务只支持 UTC

Cloudflare Cron Triggers 按 UTC 运行。所以,把上面的表达式复制到 Worker 后,它会在 UTC 09:00 执行,不受我们工具中预览时区的影响。

如果任务必须按当地时间执行,可以选择支持地区时区的调度服务,随夏令时手动调整排程,或让触发器更频繁地运行,再由程序判断当地日期、时间,并记录当天是否已经执行过。仅靠一条固定 UTC 排程,无法让任务在有夏令时的城市全年都保持上午 9 点运行。

还有一个容易忽略的区别:不同 cron 实现对星期数字的定义不同。Cloudflare 用 1 表示星期日,我们的构建器则采用常见的 0 表示星期日的规则。如果目标服务支持,建议使用 MON-FRI 这样的星期名称,部署前再核对它的文档。

上线前检查特殊日期

预览夏令时切换前后各一周的运行时间。对于每月执行的任务,还要检查二月和没有 31 日的月份。

切换夏令时时,02:30 这样的凌晨时间可能不存在,也可能出现两次。不同服务的处理方式可能不同。先决定是跳过、延迟还是避免重复执行,再到实际使用的服务里测试。其他解析器给出的预览不能保证你的服务也会这样运行。

2026 年 10 月 1 日,我们用工具实际采用的时区解析器检查了这些时间戳,并核对了对应的当地时间。测试结果记录了输入和输出。本例没有部署或运行真实的定时任务。