Cron 表达式生成器指南:五段表达式与时区坑

更新 2026-08-08 约 13 分钟 开发工具 How-to

服务器要定时跑脚本、每天凌晨 3 点清理缓存、每周一 9 点同步数据……这些计划任务用 Cron 表达式 写。写错分隔符、搞混星期与日期、或不考虑时区,就会「跑了却没按预期」。本指南讲清楚五段语法、特殊符号、预设、时区坑,配套 WebUtils 页面上的可操作步骤与决策表。

立即使用相关工具 Cron 生成器 — 本地五段表达式、预设与描述
打开工具 →

核心一句话

五段表达式:分钟 小时 日期 月份 星期;预设+描述+时区三板斧。

WebUtils 提供可视化字段、九个预设与实时自然语言描述,主工具:Cron 表达式生成器

Cron 语法详解

标准 Linux Cron(5 位):

字段 取值范围 特殊符号 含义
分钟 0-59 * / - 0-59 分钟
小时 0-23 * / - 0-23 小时
日期 1-31 * / - 每月第几天
月份 1-12 * / - 1-12 月
星期 0-7 * / - 0=周日、7=周六

6 位 Cron(秒)有秒字段。时区 由 crontab 文件或 cron -l 决定,本工具描述不包含时区(页面仅显示表达式)。

在 WebUtils 上怎么做

工具页:Cron 表达式生成器

手动字段

  1. 打开页面,找到 Cron 表达式 区域。
  2. 五个输入框(分钟 小时 日期 月份 星期)依次填 0-590-231-311-120-7
  3. 页面实时:上方 表达式 框显示 min hour dom mon dow,下方 描述 框给出自然语言解释(如「每小时整点」)。
  4. 复制 带走表达式。
  5. 清空 重置。

预设

页面有 常用预设 网格,点击按钮即自动填字段并刷新描述。示例:

  • * → 每分钟
  • 0 9 1-5 → 每天 9:00-17:00 工作时间
  • 0 0 1 → 每月 1 号午夜

能力边界

  • 有: 五字段手动、九个预设、实时描述、复制。
  • 无: 6 位秒级字段、时区选择(服务器端决定)、复杂 ? 占位符。
  • 不替代: 生产 crontab 需确认服务器时区与权限。

常见错误与对照

现象 原因 处理
任务跑但不是预想时间 星期日用 0/7,日期用 1-31 混淆 统一:日期不填则 *,星期日用 0
描述「每天 9 点」却跑 8 点 时区差 1 小时 服务器端 crontab 文件需确认时区
预设 0 9-17 1-5 没按预期 日期字段用了 9-17(非法) 只用合法范围,日期用 *
任务莫名多跑 多个字段用 /*/2 意为每隔 确认 */2 仅在该字段
描述区空 输入值有非法字符 输入 *0-59 范围数字
生产跑但日志无记录 权限、crontab 文件错误、时区 crontab -l 验证;改用 sudo crontab -e

排错顺序

  1. 确认字段范围与特殊符号。
  2. 比对描述与预期。
  3. 检查服务器时区与 crontab -l
  4. 最小可复现表达式测试。

真实工作场景

场景 A:每天凌晨 3 点清理缓存

0 3 * → 每天 03:00 执行。描述区显示「每天凌晨 3:00」。若服务器时区是 UTC+8,任务在 03:00 触发。

场景 B:每周一 9 点同步数据

0 9 1 → 星期一(0=周日)09:00。预设网格里「每周一」即选此。避免用 1(日期)混 1(星期)。

场景 C:每 5 分钟刷新一次

/5 * → 每分钟 0、5、10、15、20、25、30、35、40、45、50、55 分钟执行。描述区「每隔 5 分钟」。

场景 D:每月 1 号 0 点备份

0 0 1 → 每月 1 号午夜。日期字段 1,月份 *

场景 E:工作时间 9:00-17:00 每小时

0 9-17 1-5 → 星期一至五,09:00-17:00 每小时。日期用 *。若日期也填 9-17 会报错或非法。

场景 F:时区坑

服务器时区 UTC+8,0 3 * 跑 03:00;若你本地电脑 UTC+0,描述看「每天凌晨 3:00」但实际可能跑 15:00。生产 crontab 需确认 date 命令显示的时区。

安全与运维最佳实践

  • 生产任务最小权限:crontab -l 确认无 root 以外命令。
  • 备份 crontab:crontab -l > cron.bak
  • 测试环境先跑;线上勿跑大文件任务。
  • 描述区与实际表达式保持一致,写进运维手册。
  • 不要把密钥或敏感路径放进 cron 命令。
  • 定期 crontab -l 检查,避免过期任务。
  • 时区用 TZ=UTC-8 crontab -e 显式指定,或用系统时区常量。

实践清单

  • 生产表达式写死,不要依赖预设。
  • 最小可复现测试所有预设。
  • 确认服务器 date 命令显示时区。
  • 任务跑后看日志,确认是否按预期触发。
  • 团队约定:日期字段与星期字段分别用 *0-7
  • 备份 crontab 文件。
  • 勿把 cron 命令放进可公开的文档。

常见问题

为什么我的 cron 跑了却没按预期时间?

确认服务器时区。crontab -l 显示的时区与 date 命令一致。描述区仅表达表达式,不含时区。

日期字段和星期字段怎么选?

日期(1-31)控制每月第几天,星期(0-7)控制星期几。两者常配合:日期 * + 星期 1-5 工作日。

预设 `0 9-17 * * 1-5` 是什么意思?

每天 09:00-17:00(每小时)在星期一至五执行。日期用 *

6 位 Cron 怎么办?

Linux 默认 5 位。sudo crontab -e 后在最后一行加秒字段(如 0 0 0 0 0 0 )。

时区坑是什么?

服务器与客户端时区不同。0 3 * 在 UTC+8 跑 03:00,在 UTC+0 跑 15:00。生产 crontab 显式指定 TZ。

描述区与实际执行不一致怎么办?

表达式写对了,描述应一致。描述区由工具推导,若有特殊符号(如 */2)描述可能简化为「每隔 2 分钟」。

在线工具会上传我的 cron 吗?

页面本地计算,但表达式的实际执行依赖服务器。敏感命令勿在工具里长期粘贴。

生产环境的时间与并发边界

Cron 只负责在某个时间点启动命令,不负责保证上一次任务已经结束。如果 /5 * 的脚本偶尔运行超过 5 分钟,下一次触发可能与上一实例重叠,造成重复扣款、同时写同一文件或把外部接口打爆。对有副作用的任务,应在脚本内加锁,或使用系统提供的 flock、队列和幂等键;生成器只能生成时间表达式,不能替你解决并发控制。

夏令时切换也会产生特殊结果。跳过一个小时的日期里,0 2 * 可能不会执行;重复一个小时的日期里,它可能执行两次,具体行为取决于 cron 实现。涉及结算、提醒或跨地区业务时,优先使用带时区和日历语义的调度平台,并在测试环境模拟切换日。普通服务器的 date 输出和应用容器的时区设置也可能不同,不能只看笔记本电脑的时钟。

上线前先把命令改成写入时间戳的探针,例如 echo $(date) >> /tmp/job.log,确认用户、路径和时区后再替换为正式脚本。Cron 的环境变量通常比交互式终端少,PATH、工作目录、凭据和代理地址可能缺失;脚本应使用绝对路径并显式加载必要配置。日志要包含开始、结束、退出码和输入批次,失败时设置非零退出码,方便监控系统报警。

如果同一表达式既配置在用户 crontab 又配置在 /etc/cron.d,任务会重复运行。排查时把 crontab -l、系统目录和容器编排配置一起搜索,再临时禁用副本。生成器输出通过语法检查只是第一关,真正上线还要进行一次小范围、可回滚的演练。

发布前的观测与回滚

定时任务上线前,先把正式命令替换成只写日志的探针,验证触发时间、运行用户、工作目录和环境变量。探针至少记录开始时间、结束时间、退出码、输入批次和生成文件的位置;确认日志能被监控系统采集后,再切回正式命令。这样可以区分“没有触发”“触发但找不到命令”和“命令执行后返回错误”三类问题。

有副作用的任务还要设计幂等和回滚。比如每天结算不能因为重试而重复扣款,清理脚本不能把最近备份一起删除,发送通知要保存业务批次号以便去重。表达式通过生成器检查,只说明五段语法可解析,并不说明业务动作安全。上线时采用小范围演练,保留上一版 crontab 和脚本版本,出现异常就先停用副本,再恢复稳定版本。

继续浏览

另外要检查任务使用的权限。Cron 可能以不同于登录用户的账号运行,读取配置文件、访问网络和写入目录的权限也会不同。把脚本需要的目录、凭据和代理配置列成清单,使用最小权限账号做一次演练;不要为了让任务“先跑起来”就给出全盘写权限。容器环境还要确认容器是否会重启、时区是否继承宿主机,以及持久化日志是否会在实例销毁后丢失。

排查时还要确认命令的退出码。很多脚本打印了错误却仍然返回 0,监控系统会把失败当成成功;相反,依赖外部服务的短暂超时也不应无限重试。为每个任务写清重试次数、退避间隔和最终告警条件,并把重复执行的影响记录在运维手册中。这样生成器负责表达“什么时候运行”,脚本和监控才负责表达“运行失败后怎么办”。

0 3 走一次「预设 → 描述 → 复制」,再用 0 0 1 * 测试每月 1 号,即可覆盖最常见坑。