明明在 RRULE 里明确设置了“每周一 09:00 执行”,结果系统不仅在周二自动运行了一次,还提示“下次执行是周三”——这显然不是我们期望的结果。下面我们来深入剖析这个 WorkBuddy 自动化调度中的 BYDAY 解析 Bug,弄清楚问题到底出在哪里。
一、问题概述
配置了一个基于 RRULE 规则、本应只在每周一 09:00 触发的自动化任务,实际运行中却在周二也被执行了,并且调度器计算出的下一次执行时间显示为周三,BYDAY=MO 的限制完全被忽略。

二、环境信息
| 项目 | 详情 |
|---|---|
| WorkBuddy 平台 | macOS Desktop 客户端 |
| 自动化名称 | App Store 教育榜周报(每周一 09:00) |
| 自动化 ID | automation-1782095024956 |
| RRULE 配置 | FREQ=WEEKLY;BYDAY=MO;BYHOUR=9;BYMINUTE=0;BYSECOND=0 |
| 期望行为 | 每周一 09:00 执行一次 |
| 实际行为 | 周一执行后,周二又执行了一次,下次执行显示周三 |
三、复现步骤
- 创建一个新的自动化任务,scheduleType 设为 recurring
- RRULE 设置为:RRULE:FREQ=WEEKLY;BYDAY=MO;BYHOUR=9;BYMINUTE=0;BYSECOND=0
- 保存并激活自动化
- 首次运行正常,在周一触发
- 次日(周二)观察,自动化再次在 09:10 左右触发
四、关键证据
4.1 自动化配置(正常)
name: App Store 教育榜周报(每周一 09:00)
status: ACTIVE
scheduleType: recurring
rrule: RRULE:FREQ=WEEKLY;BYDAY=MO;BYHOUR=9;BYMINUTE=0;BYSECOND=0
4.2 实际执行记录(异常)
| 执行时间 | 星期 | 是否符合预期 |
|---|---|---|
| 2026-06-22 11:28 | 周一 | ✅ 首次创建时触发(非 RRULE 调度) |
| 2026-06-23 09:14 | 周二 | ❌ 不应执行 |
| 2026-06-24 08:50(预期) | 周三 | ❌ next_run_at 仍然不对 |
4.3 数据库验证
直接从 ~/.workbuddy/workbuddy.db 查询:
SELECT last_run_at, next_run_at FROM automation_runtime_state
WHERE automation_id = 'automation-1782095024956';
结果:
last_run_at: 1782177276881 → 2026-06-23 09:14:36 (周二) ❌
next_run_at: 1782262200000 → 2026-06-24 08:50:00 (周三) ❌
4.4 日志证据
[2026-06-22 Mon 11:28] 首次运行成功(手动/创建触发)
[2026-06-23 Tue 09:10] 调度器自动触发运行 ← 不应触发
[2026-06-24 Wed 08:50] 下次计划运行 ← next_run_at 仍有误
五、问题分析
BYDAY=MO 限制失效:RRULE 中明确指定只在周一执行,但调度器实际在周二触发了执行。
next_run_at 计算错误:当前时间为周二,按 RRULE 下次执行应为下周一(06-29),但数据库显示为周三(06-24)。
时间偏移:配置 BYHOUR=9,但实际触发在 09:14,next_run_at 显示 08:50,存在约 10 分钟偏差,疑似时区处理问题(UTC+8 vs UTC+0)。
根本猜测:调度引擎在解析包含 BYHOUR/BYMINUTE/BYSECOND 的 WEEKLY BYDAY 规则时,可能错误地忽略了 BYDAY 限制,导致退化为“每天 BYHOUR 时间执行”。
六、影响范围
所有使用 WEEKLY + BYDAY + BYHOUR 组合 RRULE 的自动化任务都可能受到影响。会导致远超预期的执行次数,浪费积分额度;对于涉及外部 API 调用、邮件发送等有副作用的自动化,可能造成骚扰或资源浪费。
七、临时规避方案
在平台修复前,只能手动暂停自动化(status = PAUSED),等到周一再手动激活。但这样一来,自动化的意义就大打折扣了。
八、建议修复方向
检查 RRULE 解析器中 BYDAY 与 WEEKLY 频率的组合逻辑;确认 DTSTART 的时区处理是否正确;自动化创建后的首次调度是否引入了偏移。另外,建议增加调度预览功能,让用户能看到未来 5 次执行时间,便于提前发现此类问题。
