服务器时区从 UTC 改为 Asia/Shanghai 之后,原来每天执行的 cron 任务突然停止运行。日志里没有报错,也没有「任务跳过」的提示——就是静默消失了。
手动触发还能正常跑,但定时触发再也不来了。
OpenClaw 的 cron 调度器判断「今天是否已执行」时,会对比当前时间和 lastRunAt 字段。时区切换前,lastRunAt 存储的是 UTC 时间戳,比如 2026-03-16T20:00:00Z(对应北京时间 3 月 17 日凌晨 4 点)。
切换到 Asia/Shanghai 后,调度器用本地时间计算「今天」——结果发现 lastRunAt 对应的本地日期已经是「今天」,于是判定任务今日已执行,跳过。
这个误判不会产生任何报错,因为从调度器的角度来看,一切正常。
# 查看当前系统时区
timedatectl status
# 检查 cron job 的 lastRunAt 字段
cat ~/.openclaw/cron/jobs.json | jq '.[] | {name, lastRunAt, timezone}'
# 确认任务是否有 timezone 字段
cat ~/.openclaw/cron/jobs.json | jq '.[] | select(.timezone == null) | .name'
如果某个任务缺少 timezone 字段,且 lastRunAt 的值对应到当地时间「今天」,那就是这个问题。
Before(有问题的配置):
{
"name": "daily-report",
"schedule": "0 9 * * *",
"lastRunAt": "2026-03-16T20:00:00Z"
}
After(修复后):
{
"name": "daily-report",
"schedule": "0 9 * * *",
"timezone": "Asia/Shanghai",
"lastRunAt": null
}
两个动作缺一不可:
1. 加上 "timezone": "Asia/Shanghai" 声明
2. 把 lastRunAt 清空为 null(让调度器重新计算)
1. 新建 cron job 时必须写 timezone
即使服务器已经是正确时区,显式声明 timezone 字段可以让配置不受系统时区影响,迁移到其他机器也不会出问题。
2. 关键任务加结果校验
光看 exitCode 不够——任务被跳过时根本不会有 exit code。建议在任务执行后,发一条消息到飞书/Slack,内容包含执行时间和关键输出。
# 任务脚本末尾加上
curl -s -X POST "$FEISHU_WEBHOOK" \
-H 'Content-Type: application/json' \
-d "{\"msg_type\":\"text\",\"content\":{\"text\":\"✅ daily-report 执行完成 $(date '+%Y-%m-%d %H:%M:%S')\"}}"
3. 时区切换后全量检查
任何时区变更后,用 jq 批量检查所有 job 的 timezone 字段,不要靠记忆判断哪些任务受影响。