GO语言实现一个自定义的可按日周月执行的定时任务,精确到分钟

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()


最后编辑于:2024/01/04作者: 牛逼PHP

发表评论