fix monthly jobs when counting days from the end (#662)
This commit is contained in:
@@ -756,32 +756,37 @@ type monthlyJob struct {
|
||||
func (m monthlyJob) next(lastRun time.Time) time.Time {
|
||||
daysList := make([]int, len(m.days))
|
||||
copy(daysList, m.days)
|
||||
firstDayNextMonth := time.Date(lastRun.Year(), lastRun.Month()+1, 1, 0, 0, 0, 0, lastRun.Location())
|
||||
for _, daySub := range m.daysFromEnd {
|
||||
// getting a combined list of all the daysList and the negative daysList
|
||||
// which count backwards from the first day of the next month
|
||||
// -1 == the last day of the month
|
||||
day := firstDayNextMonth.AddDate(0, 0, daySub).Day()
|
||||
daysList = append(daysList, day)
|
||||
}
|
||||
slices.Sort(daysList)
|
||||
|
||||
firstPass := true
|
||||
next := m.nextMonthDayAtTime(lastRun, daysList, firstPass)
|
||||
daysFromEnd := m.handleNegativeDays(lastRun, daysList, m.daysFromEnd)
|
||||
next := m.nextMonthDayAtTime(lastRun, daysFromEnd, true)
|
||||
if !next.IsZero() {
|
||||
return next
|
||||
}
|
||||
firstPass = false
|
||||
|
||||
from := time.Date(lastRun.Year(), lastRun.Month()+time.Month(m.interval), 1, 0, 0, 0, 0, lastRun.Location())
|
||||
for next.IsZero() {
|
||||
next = m.nextMonthDayAtTime(from, daysList, firstPass)
|
||||
daysFromEnd = m.handleNegativeDays(from, daysList, m.daysFromEnd)
|
||||
next = m.nextMonthDayAtTime(from, daysFromEnd, false)
|
||||
from = from.AddDate(0, int(m.interval), 0)
|
||||
}
|
||||
|
||||
return next
|
||||
}
|
||||
|
||||
func (m monthlyJob) handleNegativeDays(from time.Time, days, negativeDays []int) []int {
|
||||
var out []int
|
||||
// getting a list of the days from the end of the following month
|
||||
// -1 == the last day of the month
|
||||
firstDayNextMonth := time.Date(from.Year(), from.Month()+1, 1, 0, 0, 0, 0, from.Location())
|
||||
for _, daySub := range negativeDays {
|
||||
day := firstDayNextMonth.AddDate(0, 0, daySub).Day()
|
||||
out = append(out, day)
|
||||
}
|
||||
out = append(out, days...)
|
||||
slices.Sort(out)
|
||||
return out
|
||||
}
|
||||
|
||||
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
|
||||
for _, day := range days {
|
||||
|
||||
+36
@@ -257,6 +257,42 @@ func TestMonthlyJob_next(t *testing.T) {
|
||||
time.Date(2000, 8, 31, 5, 30, 0, 0, time.UTC),
|
||||
244 * 24 * time.Hour,
|
||||
},
|
||||
{
|
||||
"handle -1 with differing month's day count",
|
||||
1,
|
||||
nil,
|
||||
[]int{-1},
|
||||
[]time.Time{
|
||||
time.Date(0, 0, 0, 5, 30, 0, 0, time.UTC),
|
||||
},
|
||||
time.Date(2024, 1, 31, 5, 30, 0, 0, time.UTC),
|
||||
time.Date(2024, 2, 29, 5, 30, 0, 0, time.UTC),
|
||||
29 * 24 * time.Hour,
|
||||
},
|
||||
{
|
||||
"handle -1 with another differing month's day count",
|
||||
1,
|
||||
nil,
|
||||
[]int{-1},
|
||||
[]time.Time{
|
||||
time.Date(0, 0, 0, 5, 30, 0, 0, time.UTC),
|
||||
},
|
||||
time.Date(2024, 2, 29, 5, 30, 0, 0, time.UTC),
|
||||
time.Date(2024, 3, 31, 5, 30, 0, 0, time.UTC),
|
||||
31 * 24 * time.Hour,
|
||||
},
|
||||
{
|
||||
"handle -1 every 3 months next run in February",
|
||||
3,
|
||||
nil,
|
||||
[]int{-1},
|
||||
[]time.Time{
|
||||
time.Date(0, 0, 0, 5, 30, 0, 0, time.UTC),
|
||||
},
|
||||
time.Date(2023, 11, 30, 5, 30, 0, 0, time.UTC),
|
||||
time.Date(2024, 2, 29, 5, 30, 0, 0, time.UTC),
|
||||
91 * 24 * time.Hour,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
|
||||
Reference in New Issue
Block a user