Files
timerx/next_time.go
T

118 lines
4.0 KiB
Go
Raw Normal View History

2024-05-20 09:35:12 +08:00
package timerx
import (
"errors"
"time"
)
// 计算该任务下次执行时间
// @param job *JobData 任务数据
// @return time.Time 下次执行时间
2024-05-30 11:02:44 +08:00
func GetNextTime(t time.Time, job JobData) (*time.Time, error) {
2024-05-20 09:35:12 +08:00
var next time.Time
switch job.JobType {
case JobTypeEveryMonth:
2024-05-30 11:02:44 +08:00
next = calculateNextMonthTime(t, job)
2024-05-20 09:35:12 +08:00
case JobTypeEveryWeek:
2024-05-30 11:02:44 +08:00
next = calculateNextWeekTime(t, job)
2024-05-20 09:35:12 +08:00
case JobTypeEveryDay:
2024-05-30 11:02:44 +08:00
next = calculateNextDayTime(t, job)
2024-05-20 09:35:12 +08:00
case JobTypeEveryHour:
2024-05-30 11:02:44 +08:00
next = calculateNextHourTime(t, job)
2024-05-20 09:35:12 +08:00
case JobTypeEveryMinute:
2024-05-30 11:02:44 +08:00
next = calculateNextMinuteTime(t, job)
2024-05-20 09:35:12 +08:00
case JobTypeInterval:
next = calculateNextInterval(t, job)
default:
return nil, errors.New("未知的任务类型: " + string(job.JobType))
}
return &next, nil
}
func calculateNextInterval(t time.Time, job JobData) time.Time {
// 从创建的时候开始计算
2024-05-22 15:02:39 +08:00
cycle := t.Sub(job.BaseTime).Microseconds() / job.IntervalTime.Microseconds()
return job.BaseTime.Add(job.IntervalTime * time.Duration(cycle+1))
2024-05-20 09:35:12 +08:00
}
2024-05-30 11:02:44 +08:00
func calculateNextMonthTime(t time.Time, job JobData) time.Time {
2024-05-20 09:35:12 +08:00
// 判断是否可执行并返回下一个执行时间
2024-05-30 11:02:44 +08:00
2024-05-20 09:35:12 +08:00
if canRun(t, job) {
2024-05-30 11:02:44 +08:00
return time.Date(t.Year(), t.Month(), job.Day, job.Hour, job.Minute, job.Second, 0, t.Location())
2024-05-20 09:35:12 +08:00
}
// 下一个周期(下个月)
2024-05-30 11:02:44 +08:00
return time.Date(t.Year(), t.Month()+1, job.Day, job.Hour, job.Minute, job.Second, 0, t.Location())
2024-05-20 09:35:12 +08:00
}
2024-05-30 11:02:44 +08:00
func calculateNextWeekTime(t time.Time, job JobData) time.Time {
2024-05-20 09:35:12 +08:00
weekday := t.Weekday()
days := int(job.Weekday - weekday)
if days < 0 {
days += 7
}
// 判断是否可执行并返回下一个执行时间
if canRun(t, job) {
2024-05-30 11:02:44 +08:00
return time.Date(t.Year(), t.Month(), t.Day(), job.Hour, job.Minute, job.Second, 0, t.Location())
2024-05-20 09:35:12 +08:00
}
// 下一个周期(下周)
2024-05-30 11:02:44 +08:00
return time.Date(t.Year(), t.Month(), t.Day()+days+7, job.Hour, job.Minute, job.Second, 0, t.Location())
2024-05-20 09:35:12 +08:00
}
2024-05-30 11:02:44 +08:00
func calculateNextDayTime(t time.Time, job JobData) time.Time {
2024-05-20 09:35:12 +08:00
// 判断是否可执行并返回下一个执行时间
if canRun(t, job) {
2024-05-30 11:02:44 +08:00
return time.Date(t.Year(), t.Month(), t.Day(), job.Hour, job.Minute, job.Second, 0, t.Location())
2024-05-20 09:35:12 +08:00
}
// 下一个周期(明天)
2024-05-30 11:02:44 +08:00
return time.Date(t.Year(), t.Month(), t.Day()+1, job.Hour, job.Minute, job.Second, 0, t.Location())
2024-05-20 09:35:12 +08:00
}
2024-05-30 11:02:44 +08:00
func calculateNextHourTime(t time.Time, job JobData) time.Time {
2024-05-20 09:35:12 +08:00
// 判断是否可执行并返回下一个执行时间
if canRun(t, job) {
2024-05-30 11:02:44 +08:00
return time.Date(t.Year(), t.Month(), t.Day(), t.Hour(), job.Minute, job.Second, 0, t.Location())
2024-05-20 09:35:12 +08:00
}
// 下一个周期(下个小时)
2024-05-30 11:02:44 +08:00
return time.Date(t.Year(), t.Month(), t.Day(), t.Hour()+1, job.Minute, job.Second, 0, t.Location())
2024-05-20 09:35:12 +08:00
}
2024-05-30 11:02:44 +08:00
func calculateNextMinuteTime(t time.Time, job JobData) time.Time {
2024-05-20 09:35:12 +08:00
// 判断是否可执行并返回下一个执行时间
if canRun(t, job) {
2024-05-30 11:02:44 +08:00
return time.Date(t.Year(), t.Month(), t.Day(), t.Hour(), t.Minute(), job.Second, 0, t.Location())
2024-05-20 09:35:12 +08:00
}
// 下一个周期(下分钟)
2024-05-30 11:02:44 +08:00
return time.Date(t.Year(), t.Month(), t.Day(), t.Hour(), t.Minute()+1, job.Second, 0, t.Location())
2024-05-20 09:35:12 +08:00
}
// 检查是否本周期可以运行
func canRun(t time.Time, job JobData) bool {
switch job.JobType {
case JobTypeEveryMonth:
return t.Day() < job.Day ||
(t.Day() == job.Day && t.Hour() < job.Hour) ||
(t.Day() == job.Day && t.Hour() == job.Hour && t.Minute() < job.Minute) ||
(t.Day() == job.Day && t.Hour() == job.Hour && t.Minute() == job.Minute && t.Second() <= job.Second)
case JobTypeEveryWeek:
return t.Weekday() < job.Weekday ||
(t.Weekday() == job.Weekday && t.Hour() < job.Hour) ||
(t.Weekday() == job.Weekday && t.Hour() == job.Hour && t.Minute() < job.Minute) ||
(t.Weekday() == job.Weekday && t.Hour() == job.Hour && t.Minute() == job.Minute && t.Second() <= job.Second)
case JobTypeEveryDay:
return t.Hour() < job.Hour ||
(t.Hour() == job.Hour && t.Minute() < job.Minute) ||
(t.Hour() == job.Hour && t.Minute() == job.Minute && t.Second() <= job.Second)
case JobTypeEveryHour:
return t.Minute() < job.Minute ||
(t.Minute() == job.Minute && t.Second() <= job.Second)
case JobTypeEveryMinute:
return t.Second() <= job.Second
default:
return false
}
}