fix weekly and monthly to handle midnight (#643)
This commit is contained in:
@@ -256,6 +256,7 @@ func (w weeklyJobDefinition) setup(j *internalJob, location *time.Location) erro
|
|||||||
daysOfTheWeek := w.daysOfTheWeek()
|
daysOfTheWeek := w.daysOfTheWeek()
|
||||||
|
|
||||||
slices.Sort(daysOfTheWeek)
|
slices.Sort(daysOfTheWeek)
|
||||||
|
ws.daysOfWeek = daysOfTheWeek
|
||||||
|
|
||||||
atTimesDate, err := convertAtTimesToDateTime(w.atTimes, location)
|
atTimesDate, err := convertAtTimesToDateTime(w.atTimes, location)
|
||||||
switch {
|
switch {
|
||||||
@@ -622,31 +623,31 @@ type dailyJob struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (d dailyJob) next(lastRun time.Time) time.Time {
|
func (d dailyJob) next(lastRun time.Time) time.Time {
|
||||||
return d.nextDay(lastRun)
|
firstPass := true
|
||||||
|
next := d.nextDay(lastRun, firstPass)
|
||||||
|
if !next.IsZero() {
|
||||||
|
return next
|
||||||
|
}
|
||||||
|
firstPass = false
|
||||||
|
|
||||||
|
startNextDay := time.Date(lastRun.Year(), lastRun.Month(), lastRun.Day()+int(d.interval), 0, 0, 0, lastRun.Nanosecond(), lastRun.Location())
|
||||||
|
return d.nextDay(startNextDay, firstPass)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d dailyJob) nextDay(lastRun time.Time) time.Time {
|
func (d dailyJob) nextDay(lastRun time.Time, firstPass bool) time.Time {
|
||||||
for _, at := range d.atTimes {
|
for _, at := range d.atTimes {
|
||||||
// sub the at time hour/min/sec onto the lastRun's values
|
// sub the at time hour/min/sec onto the lastRun's values
|
||||||
// to use in checks to see if we've got our next run time
|
// to use in checks to see if we've got our next run time
|
||||||
atDate := time.Date(lastRun.Year(), lastRun.Month(), lastRun.Day(), at.Hour(), at.Minute(), at.Second(), lastRun.Nanosecond(), lastRun.Location())
|
atDate := time.Date(lastRun.Year(), lastRun.Month(), lastRun.Day(), at.Hour(), at.Minute(), at.Second(), lastRun.Nanosecond(), lastRun.Location())
|
||||||
|
|
||||||
if atDate.After(lastRun) {
|
if firstPass && atDate.After(lastRun) {
|
||||||
// checking to see if it is after i.e. greater than,
|
// checking to see if it is after i.e. greater than,
|
||||||
// and not greater or equal as our lastRun day/time
|
// and not greater or equal as our lastRun day/time
|
||||||
// will be in the loop, and we don't want to select it again
|
// will be in the loop, and we don't want to select it again
|
||||||
return atDate
|
return atDate
|
||||||
}
|
} else if !firstPass && !atDate.Before(lastRun) {
|
||||||
}
|
|
||||||
startNextDay := time.Date(lastRun.Year(), lastRun.Month(), lastRun.Day()+int(d.interval), 0, 0, 0, lastRun.Nanosecond(), lastRun.Location())
|
|
||||||
for _, at := range d.atTimes {
|
|
||||||
// sub the at time hour/min/sec onto the lastRun's values
|
|
||||||
// to use in checks to see if we've got our next run time
|
|
||||||
atDate := time.Date(startNextDay.Year(), startNextDay.Month(), startNextDay.Day(), at.Hour(), at.Minute(), at.Second(), startNextDay.Nanosecond(), startNextDay.Location())
|
|
||||||
|
|
||||||
if !atDate.Before(startNextDay) {
|
|
||||||
// now that we're looking at the next day, it's ok to consider
|
// now that we're looking at the next day, it's ok to consider
|
||||||
// the same at time that was last run
|
// the same at time that was last run (as lastRun has been incremented)
|
||||||
return atDate
|
return atDate
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -662,17 +663,19 @@ type weeklyJob struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (w weeklyJob) next(lastRun time.Time) time.Time {
|
func (w weeklyJob) next(lastRun time.Time) time.Time {
|
||||||
next := w.nextWeekDayAtTime(lastRun)
|
firstPass := true
|
||||||
|
next := w.nextWeekDayAtTime(lastRun, firstPass)
|
||||||
if !next.IsZero() {
|
if !next.IsZero() {
|
||||||
return next
|
return next
|
||||||
}
|
}
|
||||||
|
firstPass = false
|
||||||
|
|
||||||
startOfTheNextIntervalWeek := (lastRun.Day() - int(lastRun.Weekday())) + int(w.interval*7)
|
startOfTheNextIntervalWeek := (lastRun.Day() - int(lastRun.Weekday())) + int(w.interval*7)
|
||||||
from := time.Date(lastRun.Year(), lastRun.Month(), startOfTheNextIntervalWeek, 0, 0, 0, 0, lastRun.Location())
|
from := time.Date(lastRun.Year(), lastRun.Month(), startOfTheNextIntervalWeek, 0, 0, 0, 0, lastRun.Location())
|
||||||
return w.nextWeekDayAtTime(from)
|
return w.nextWeekDayAtTime(from, firstPass)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w weeklyJob) nextWeekDayAtTime(lastRun time.Time) time.Time {
|
func (w weeklyJob) nextWeekDayAtTime(lastRun time.Time, firstPass bool) time.Time {
|
||||||
for _, wd := range w.daysOfWeek {
|
for _, wd := range w.daysOfWeek {
|
||||||
// checking if we're on the same day or later in the same week
|
// checking if we're on the same day or later in the same week
|
||||||
if wd >= lastRun.Weekday() {
|
if wd >= lastRun.Weekday() {
|
||||||
@@ -683,11 +686,15 @@ func (w weeklyJob) nextWeekDayAtTime(lastRun time.Time) time.Time {
|
|||||||
// to use in checks to see if we've got our next run time
|
// to use in checks to see if we've got our next run time
|
||||||
atDate := time.Date(lastRun.Year(), lastRun.Month(), lastRun.Day()+int(weekDayDiff), at.Hour(), at.Minute(), at.Second(), lastRun.Nanosecond(), lastRun.Location())
|
atDate := time.Date(lastRun.Year(), lastRun.Month(), lastRun.Day()+int(weekDayDiff), at.Hour(), at.Minute(), at.Second(), lastRun.Nanosecond(), lastRun.Location())
|
||||||
|
|
||||||
if atDate.After(lastRun) {
|
if firstPass && atDate.After(lastRun) {
|
||||||
// checking to see if it is after i.e. greater than,
|
// checking to see if it is after i.e. greater than,
|
||||||
// and not greater or equal as our lastRun day/time
|
// and not greater or equal as our lastRun day/time
|
||||||
// will be in the loop, and we don't want to select it again
|
// will be in the loop, and we don't want to select it again
|
||||||
return atDate
|
return atDate
|
||||||
|
} else if !firstPass && !atDate.Before(lastRun) {
|
||||||
|
// now that we're looking at the next week, it's ok to consider
|
||||||
|
// the same at time that was last run (as lastRun has been incremented)
|
||||||
|
return atDate
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -717,21 +724,23 @@ func (m monthlyJob) next(lastRun time.Time) time.Time {
|
|||||||
}
|
}
|
||||||
slices.Sort(daysList)
|
slices.Sort(daysList)
|
||||||
|
|
||||||
next := m.nextMonthDayAtTime(lastRun, daysList)
|
firstPass := true
|
||||||
|
next := m.nextMonthDayAtTime(lastRun, daysList, firstPass)
|
||||||
if !next.IsZero() {
|
if !next.IsZero() {
|
||||||
return next
|
return next
|
||||||
}
|
}
|
||||||
|
firstPass = false
|
||||||
|
|
||||||
from := time.Date(lastRun.Year(), lastRun.Month()+time.Month(m.interval), 1, 0, 0, 0, 0, lastRun.Location())
|
from := time.Date(lastRun.Year(), lastRun.Month()+time.Month(m.interval), 1, 0, 0, 0, 0, lastRun.Location())
|
||||||
for next.IsZero() {
|
for next.IsZero() {
|
||||||
next = m.nextMonthDayAtTime(from, daysList)
|
next = m.nextMonthDayAtTime(from, daysList, firstPass)
|
||||||
from = from.AddDate(0, int(m.interval), 0)
|
from = from.AddDate(0, int(m.interval), 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
return next
|
return next
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m monthlyJob) nextMonthDayAtTime(lastRun time.Time, days []int) time.Time {
|
func (m monthlyJob) nextMonthDayAtTime(lastRun time.Time, days []int, firstPass bool) time.Time {
|
||||||
// find the next day in the month that should run and then check for an at time
|
// find the next day in the month that should run and then check for an at time
|
||||||
for _, day := range days {
|
for _, day := range days {
|
||||||
if day >= lastRun.Day() {
|
if day >= lastRun.Day() {
|
||||||
@@ -746,11 +755,15 @@ func (m monthlyJob) nextMonthDayAtTime(lastRun time.Time, days []int) time.Time
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if atDate.After(lastRun) {
|
if firstPass && atDate.After(lastRun) {
|
||||||
// checking to see if it is after i.e. greater than,
|
// checking to see if it is after i.e. greater than,
|
||||||
// and not greater or equal as our lastRun day/time
|
// and not greater or equal as our lastRun day/time
|
||||||
// will be in the loop, and we don't want to select it again
|
// will be in the loop, and we don't want to select it again
|
||||||
return atDate
|
return atDate
|
||||||
|
} else if !firstPass && !atDate.Before(lastRun) {
|
||||||
|
// now that we're looking at the next month, it's ok to consider
|
||||||
|
// the same at time that was lastRun (as lastRun has been incremented)
|
||||||
|
return atDate
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
|
|||||||
+6
-6
@@ -113,10 +113,10 @@ func TestWeeklyJob_next(t *testing.T) {
|
|||||||
1,
|
1,
|
||||||
[]time.Weekday{time.Monday, time.Thursday},
|
[]time.Weekday{time.Monday, time.Thursday},
|
||||||
[]time.Time{
|
[]time.Time{
|
||||||
time.Date(0, 0, 0, 5, 30, 0, 0, time.UTC),
|
time.Date(0, 0, 0, 0, 0, 0, 0, time.UTC),
|
||||||
},
|
},
|
||||||
time.Date(2000, 1, 3, 5, 30, 0, 0, time.UTC),
|
time.Date(2000, 1, 3, 0, 0, 0, 0, time.UTC),
|
||||||
time.Date(2000, 1, 6, 5, 30, 0, 0, time.UTC),
|
time.Date(2000, 1, 6, 0, 0, 0, 0, time.UTC),
|
||||||
3 * 24 * time.Hour,
|
3 * 24 * time.Hour,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -179,10 +179,10 @@ func TestMonthlyJob_next(t *testing.T) {
|
|||||||
[]int{1, 10},
|
[]int{1, 10},
|
||||||
nil,
|
nil,
|
||||||
[]time.Time{
|
[]time.Time{
|
||||||
time.Date(0, 0, 0, 5, 30, 0, 0, time.UTC),
|
time.Date(0, 0, 0, 0, 0, 0, 0, time.UTC),
|
||||||
},
|
},
|
||||||
time.Date(2000, 1, 1, 5, 30, 0, 0, time.UTC),
|
time.Date(2000, 1, 1, 0, 0, 0, 0, time.UTC),
|
||||||
time.Date(2000, 1, 10, 5, 30, 0, 0, time.UTC),
|
time.Date(2000, 1, 10, 0, 0, 0, 0, time.UTC),
|
||||||
9 * 24 * time.Hour,
|
9 * 24 * time.Hour,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user