GO语言实现一个自定义的可按日周月执行的定时任务,精确到分钟
package scheduletask import ( "fmt" "log" "time" ) type TaskType int const ( Daily TaskType = iota Weekly Monthly ) type Task struct { Time time.Time Func func() error TaskType TaskType } type ScheduledTask struct { tasks []Task } // NewScheduledTask 函数用于创建一个新的ScheduledTask实例 // 返回值为指向ScheduledTask实例的指针 func NewScheduledTask() *ScheduledTask { return &ScheduledTask{} } // AddTask 将任务添加到ScheduledTask实例的tasks切片中 func (st *ScheduledTask) AddTask(task Task) { st.tasks = append(st.tasks, task) } // execTask 是一个ScheduledTask的方法,用于执行任务。 func (st *ScheduledTask) execTask() { for { now := time.Now() for _, task := range st.tasks { go func(t Task) { switch t.TaskType { case Daily: if now.Hour() == t.Time.Hour() && now.Minute() == t.Time.Minute() { err := t.Func() if err != nil { log.Println("Executing daily task failed:", err) } } case Weekly: if now.Weekday() == t.Time.Weekday() && now.Hour() == t.Time.Hour() && now.Minute() == t.Time.Minute() { err := t.Func() if err != nil { log.Println("Executing weekly task failed:", err) } } case Monthly: if now.Day() == t.Time.Day() && now.Hour() == t.Time.Hour() && now.Minute() == t.Time.Minute() { err := t.Func() if err != nil { log.Println("Executing monthly task failed:", err) } } } }(task) } time.Sleep(1 * time.Minute) // 每分钟检查一次 } } // Start 方法启动ScheduledTask的执行 func (st *ScheduledTask) Start() { go func() { for { task := st func() { defer func() { if r := recover(); r != nil { fmt.Println("ScheduledTask Recovered from panic:", r) log.Fatalln("ScheduledTask Recovered from panic:", r) } }() task.execTask() }() } }() } // GenerateTime 函数用于生成一个指定小时和分钟的当前时间 // 参数hour表示小时,min表示分钟 // 返回值为time.Time类型,表示指定小时和分钟的当前时间 func GenerateTime(hour, min int) time.Time { now := time.Now() return time.Date(now.Year(), now.Month(), now.Day(), hour, min, 0, 0, now.Location()) } // GenerateTimeByWeekday 根据指定的星期几和时间生成一个时间 // 参数 weekday: 指定的星期几,使用 time.Weekday 类型表示 // 参数 hour: 小时数,取值范围为 0-23 // 参数 min: 分钟数,取值范围为 0-59 // 返回值 time.Time: 生成的指定时间 func GenerateTimeByWeekday(weekday time.Weekday, hour, min int) time.Time { now := time.Now() for now.Weekday() != weekday { now = now.AddDate(0, 0, 1) } return time.Date(now.Year(), now.Month(), now.Day(), hour, min, 0, 0, now.Location()) } // GenerateTimeByDay 根据指定的日期、小时和分钟返回一个时间类型 // // 参数: // // day - int 指定的日期(日) // hour - int 指定的时间(小时) // min - int 指定的时间(分钟) // // 返回值: // // time.Time - 返回一个时间类型,表示指定的日期和时间 func GenerateTimeByDay(day, hour, min int) time.Time { now := time.Now() year, month, _ := now.Date() return time.Date(year, month, day, hour, min, 0, 0, now.Location()) }
用法:
task := scheduletask.NewScheduledTask() // 添加每天的任务 dailyTask := scheduletask.Task{ Time: scheduletask.GenerateTime(9, 0), Func: tasks.GenerateDailyBudgetConsumptionRateReportByRuliuRobot, TaskType: scheduletask.Daily, } task.AddTask(dailyTask) // // 添加每周的任务 // weeklyTask := scheduletask.Task{ // Time: scheduletask.GenerateTimeByWeekday(time.Thursday, 9, 20), // Func: func() { fmt.Println("每周任务") }, // TaskType: scheduletask.Weekly, // } // task.AddTask(weeklyTask) // // 添加每月的任务 // monthlyTask := scheduletask.Task{ // Time: scheduletask.GenerateTimeByDay(28, 9, 10), // Func: func() { fmt.Println("每月任务") }, // TaskType: scheduletask.Monthly, // } // task.AddTask(monthlyTask) task.Start()
发表评论