
聊天式助理最常見的命令不是 RFC 3339,而是「10 分鐘後」、「兩小時後」、「明天下午三點」。今天先完成可預測的中文子集,遇到模糊日期就追問,不假裝全部理解。
時間解析最危險的錯誤不是報錯,而是安靜地排到錯的時間。因此 deterministic parser 只接受明確 pattern;「晚點」、「下週有空時」交給 Gemini 追問。
extractTime(text, now, timeZone) 支援:
10 分鐘後
2 小時後
明天上午 9 點
明天下午 3:30
解析後回傳 { at, rest },把時間片段移除,剩下的文字作為提醒內容。命令格式:
10 分鐘後提醒我喝水
明天下午 3 點提醒我追報價
提醒存成 ScheduledJob:
{
type: 'reminder',
runAt: '2026-08-12T07:00:00.000Z',
payload: { message: '追報價' },
destination: { channel, conversationId },
status: 'active'
}
所有持久時間用 ISO 8601。Parser 以 Intl.DateTimeFormat(..., { timeZone }) 取得當地年月日,再反算 UTC;不能使用執行主機的 Date.setHours(),否則 CI 在 UTC、Apps Script 在另一區域時會產生八小時偏差。預設 Asia/Taipei,也會讀取 TIME_ZONE 設定。
把測試時間固定在 2026-08-11 10:00,依序解析「10 分鐘後提醒我喝水」、「2 小時後提醒我寄信」和「明天下午 3 點提醒我追報價」。檢查 rest 分別只剩提醒內容,runAt 則是正確 ISO 字串。再把 now 放在 12 月 31 日晚上,確認「2 小時後」會自然跨年。
最後嘗試「晚點提醒我」與「明天 25 點」。前者應交由 Agent 追問,後者應由 validator 拒絕。測試的重點不是能解析多少口語,而是低信心時絕不偷偷建立錯誤排程。
測試注入固定 now,避免測試隨真實時間漂移。確認 10 分鐘、2 小時與明天下午三點的結果;跨月底、年底也要由 JavaScript Date 正確進位。
錯誤案例同樣重要:「提醒我開會」沒有時間,不應建立 runAt 為 Invalid Date;「25 點」應拒絕或追問,而非讓 Date 自動進到隔天。
day-15。下一篇執行 scheduler。日光節約時間在台北不是問題,但部署者若改時區,也不能單靠 UTC 加固定小時。目前轉換會以 IANA time zone 反覆校正 offset;仍應替部署者實際使用的 DST 切換日增加測試。
第一版只完成高信心格式,不支援農曆、國定假日或「月底前」。遇到低信心文字應由 Agent 反問具體日期。下一篇讓 scheduler 在電腦關機後真正送出提醒。