mirror of https://github.com/shunfei/cronsun
parent
baaaa5eef8
commit
b1f93a411c
@ -0,0 +1,34 @@
|
||||
package cron
|
||||
|
||||
import (
|
||||
"sort"
|
||||
"time"
|
||||
)
|
||||
|
||||
// TimeListSchedule will run at the specify giving time.
|
||||
type TimeListSchedule struct {
|
||||
timeList []time.Time
|
||||
}
|
||||
|
||||
// At returns a crontab Schedule that activates every specify time.
|
||||
func At(tl []time.Time) *TimeListSchedule {
|
||||
sort.Slice(tl, func(i, j int) bool { return tl[i].Unix() < tl[j].Unix() })
|
||||
return &TimeListSchedule{
|
||||
timeList: tl,
|
||||
}
|
||||
}
|
||||
|
||||
// Next returns the next time this should be run.
|
||||
// This rounds so that the next activation time will be on the second.
|
||||
func (schedule *TimeListSchedule) Next(t time.Time) time.Time {
|
||||
cur := 0
|
||||
for cur < len(schedule.timeList) {
|
||||
nextt := schedule.timeList[cur]
|
||||
cur++
|
||||
if nextt.UnixNano() <= t.UnixNano() {
|
||||
continue
|
||||
}
|
||||
return nextt
|
||||
}
|
||||
return time.Time{}
|
||||
}
|
@ -0,0 +1,89 @@
|
||||
package cron
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestTimeListNext(t *testing.T) {
|
||||
tests := []struct {
|
||||
startTime string
|
||||
times []string
|
||||
expected []string
|
||||
}{
|
||||
// Simple cases
|
||||
{
|
||||
"2018-09-01 08:01:02",
|
||||
[]string{"2018-09-01 10:01:02"},
|
||||
[]string{"2018-09-01 10:01:02"},
|
||||
},
|
||||
|
||||
// sort list
|
||||
{
|
||||
"2018-09-01 08:01:02",
|
||||
[]string{"2018-09-01 10:01:02", "2018-09-02 10:01:02"},
|
||||
[]string{"2018-09-01 10:01:02", "2018-09-02 10:01:02"},
|
||||
},
|
||||
|
||||
// sort list with middle start time
|
||||
{
|
||||
"2018-09-01 10:11:02",
|
||||
[]string{"2018-09-01 10:01:02", "2018-09-02 10:01:02"},
|
||||
[]string{"2018-09-02 10:01:02"},
|
||||
},
|
||||
|
||||
// unsorted list
|
||||
{
|
||||
"2018-07-01 08:01:02",
|
||||
[]string{"2018-09-01 10:01:00", "2018-08-01 10:00:00", "2018-09-01 10:00:00", "2018-08-02 10:01:02"},
|
||||
[]string{"2018-08-01 10:00:00", "2018-08-02 10:01:02", "2018-09-01 10:00:00", "2018-09-01 10:01:00"},
|
||||
},
|
||||
|
||||
// unsorted list with middle start time
|
||||
{
|
||||
"2018-08-03 12:00:00",
|
||||
[]string{"2018-09-01 10:01:00", "2018-08-01 10:00:00", "2018-09-01 10:00:00", "2018-08-02 10:01:02"},
|
||||
[]string{"2018-09-01 10:00:00", "2018-09-01 10:01:00"},
|
||||
},
|
||||
}
|
||||
|
||||
for _, c := range tests {
|
||||
tls := At(getAtTimes(c.times))
|
||||
nextTime := getAtTime(c.startTime)
|
||||
for _, trun := range c.expected {
|
||||
actual := tls.Next(nextTime)
|
||||
expected := getAtTime(trun)
|
||||
if actual != expected {
|
||||
t.Errorf("%s, \"%s\": (expected) %v != %v (actual)",
|
||||
c.startTime, c.times, expected, actual)
|
||||
}
|
||||
nextTime = actual
|
||||
}
|
||||
if actual := tls.Next(nextTime); !actual.IsZero() {
|
||||
t.Errorf("%s, \"%s\": next time should be zero, but got %v (actual)",
|
||||
c.startTime, c.times, actual)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
func getAtTime(value string) time.Time {
|
||||
if value == "" {
|
||||
panic("time string is empty")
|
||||
}
|
||||
|
||||
t, err := time.Parse("2006-01-02 15:04:05", value)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return t
|
||||
}
|
||||
|
||||
func getAtTimes(values []string) []time.Time {
|
||||
tl := []time.Time{}
|
||||
for _, v := range values {
|
||||
tl = append(tl, getAtTime(v))
|
||||
}
|
||||
return tl
|
||||
}
|
Loading…
Reference in new issue