如何让Go实现的定时任务仅在工作日执行?
让Go定时任务仅在工作日执行的修改方案
要让你的定时任务只在周一到周五运行,核心是在计算下一次执行时间时,判断目标日期是否为工作日,若为周末则自动顺延到下一个工作日。
修改核心函数 getNextTickDuration
主要修改逻辑集中在getNextTickDuration中,我们需要在计算出初始的nextTick后,循环检查其星期数,直到找到符合条件的工作日:
func getNextTickDuration() time.Duration { now := time.Now() nextTick := time.Date(now.Year(), now.Month(), now.Day(), HOUR_TO_TICK, MINUTE_TO_TICK, SECOND_TO_TICK, 0, time.Local) // 如果当前时间已经过了今日的执行时间,先把日期往后推一天 if nextTick.Before(now) { nextTick = nextTick.Add(INTERVAL_PERIOD) } // 循环检查是否为工作日,非工作日则继续往后推一天 for nextTick.Weekday() == time.Saturday || nextTick.Weekday() == time.Sunday { nextTick = nextTick.Add(INTERVAL_PERIOD) } return nextTick.Sub(time.Now()) }
完整修改后的代码
package main import ( "fmt" "time" ) const INTERVAL_PERIOD time.Duration = 24 * time.Hour const HOUR_TO_TICK int = 23 const MINUTE_TO_TICK int = 21 const SECOND_TO_TICK int = 03 type jobTicker struct { t *time.Timer } func getNextTickDuration() time.Duration { now := time.Now() nextTick := time.Date(now.Year(), now.Month(), now.Day(), HOUR_TO_TICK, MINUTE_TO_TICK, SECOND_TO_TICK, 0, time.Local) if nextTick.Before(now) { nextTick = nextTick.Add(INTERVAL_PERIOD) } // 跳过周末,仅保留周一到周五 for nextTick.Weekday() == time.Saturday || nextTick.Weekday() == time.Sunday { nextTick = nextTick.Add(INTERVAL_PERIOD) } return nextTick.Sub(time.Now()) } func NewJobTicker() jobTicker { fmt.Println("new tick here") return jobTicker{time.NewTimer(getNextTickDuration())} } func (jt jobTicker) updateJobTicker() { fmt.Println("next tick here") jt.t.Reset(getNextTickDuration()) } func main() { jt := NewJobTicker() for { <-jt.t.C fmt.Println(time.Now(), "- just ticked") jt.updateJobTicker() } }
关键逻辑说明
- Go的
time.Weekday类型中,Sunday对应0,Monday对应1,Friday对应5,Saturday对应6 - 循环判断
nextTick的星期数,如果是周六或周日,就往后加一天,直到得到周一到周五的日期 - 先处理“当前时间已过今日执行点”的情况,再检查是否为工作日,避免出现“今日过点但为周末,直接跳转到下周一”的错误
内容的提问来源于stack exchange,提问作者Awesome Lerman
相关产品推荐
相关产品推荐

