1
0
mirror of https://github.com/gogf/gf.git synced 2025-04-05 11:18:50 +08:00
gf/os/gcron/gcron_schedule_next.go

80 lines
2.3 KiB
Go

// Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
package gcron
import (
"time"
)
// Next returns the next time this schedule is activated, greater than the given
// time. If no time can be found to satisfy the schedule, return the zero time.
func (s *cronSchedule) Next(lastMeetTime time.Time) time.Time {
if s.everySeconds != 0 {
var (
diff = lastMeetTime.Unix() - s.createTimestamp
count = diff/s.everySeconds + 1
)
return lastMeetTime.Add(time.Duration(count*s.everySeconds) * time.Second)
}
var currentTime = lastMeetTime
if s.ignoreSeconds {
// Start at the earliest possible time (the upcoming minute).
currentTime = currentTime.Add(1*time.Minute - time.Duration(currentTime.Nanosecond())*time.Nanosecond)
} else {
// Start at the earliest possible time (the upcoming second).
currentTime = currentTime.Add(1*time.Second - time.Duration(currentTime.Nanosecond())*time.Nanosecond)
}
var (
loc = currentTime.Location()
yearLimit = currentTime.Year() + 5
)
WRAP:
if currentTime.Year() > yearLimit {
return currentTime // who will care the job that run in five years later
}
for !s.checkMeetMonth(currentTime) {
currentTime = currentTime.AddDate(0, 1, 0)
currentTime = time.Date(currentTime.Year(), currentTime.Month(), 1, 0, 0, 0, 0, loc)
if currentTime.Month() == time.January {
goto WRAP
}
}
for !s.checkMeetWeek(currentTime) || !s.checkMeetDay(currentTime) {
currentTime = currentTime.AddDate(0, 0, 1)
currentTime = time.Date(currentTime.Year(), currentTime.Month(), currentTime.Day(), 0, 0, 0, 0, loc)
if currentTime.Day() == 1 {
goto WRAP
}
}
for !s.checkMeetHour(currentTime) {
currentTime = currentTime.Add(time.Hour)
currentTime = currentTime.Truncate(time.Hour)
if currentTime.Hour() == 0 {
goto WRAP
}
}
for !s.checkMeetMinute(currentTime) {
currentTime = currentTime.Add(1 * time.Minute)
currentTime = currentTime.Truncate(time.Minute)
if currentTime.Minute() == 0 {
goto WRAP
}
}
for !s.checkMeetSecond(lastMeetTime, currentTime) {
currentTime = currentTime.Add(1 * time.Second)
if currentTime.Second() == 0 {
goto WRAP
}
}
return currentTime.In(loc)
}