update
This commit is contained in:
parent
1cae9d332f
commit
c1295d9e26
22
cron.go
Normal file
22
cron.go
Normal file
@ -0,0 +1,22 @@
|
||||
package startimer
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func parseCron(cron string) (StarTimer, error) {
|
||||
for {
|
||||
oldLen := len(cron)
|
||||
cron = strings.ReplaceAll(strings.TrimSpace(cron), " ", " ")
|
||||
if len(cron) == oldLen {
|
||||
break
|
||||
}
|
||||
}
|
||||
ct := strings.Split(cron, " ")
|
||||
if len(ct) != 6 {
|
||||
return StarTimer{}, errors.New("Invalid cron,argument not enough")
|
||||
}
|
||||
|
||||
return StarTimer{}, nil
|
||||
}
|
7
cron_test.go
Normal file
7
cron_test.go
Normal file
@ -0,0 +1,7 @@
|
||||
package startimer
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestParseCron(t *testing.T) {
|
||||
parseCron("0 */4 * * * *")
|
||||
}
|
116
time_test.go
116
time_test.go
@ -7,16 +7,20 @@ import (
|
||||
)
|
||||
|
||||
func TestTimer(t *testing.T) {
|
||||
tk:= StarTimer{
|
||||
base: time.Now(),
|
||||
repeat: []*Repeats{
|
||||
tk := StarTimer{
|
||||
base: time.Now(),
|
||||
repeat: []*Repeats{
|
||||
{
|
||||
Every: false,
|
||||
Every: false,
|
||||
Repeat: []Repeat{
|
||||
{
|
||||
Unit: STAR_MINUTE,
|
||||
Value: 7,
|
||||
},
|
||||
{
|
||||
Unit: STAR_HOUR,
|
||||
Value: 19,
|
||||
},
|
||||
{
|
||||
Unit: STAR_HOUR,
|
||||
Value: 18,
|
||||
@ -24,7 +28,7 @@ func TestTimer(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
Every: false,
|
||||
Every: false,
|
||||
Repeat: []Repeat{
|
||||
{
|
||||
Unit: STAR_MINUTE,
|
||||
@ -37,7 +41,7 @@ func TestTimer(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
Every: true,
|
||||
Every: true,
|
||||
Repeat: []Repeat{
|
||||
{
|
||||
Unit: STAR_HOUR,
|
||||
@ -47,9 +51,103 @@ func TestTimer(t *testing.T) {
|
||||
},
|
||||
},
|
||||
}
|
||||
base:=tk.base
|
||||
for i:=0;i<10;i++{
|
||||
base=tk.parseNextDate(base)
|
||||
base := tk.base
|
||||
for i := 0; i < 50; i++ {
|
||||
base = tk.parseNextDate(base, true)
|
||||
fmt.Println(base)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPrepareCronMax(t *testing.T) {
|
||||
var rpt = new(Repeats)
|
||||
for i := 0; i < 60; i++ {
|
||||
if i%2 != 0 {
|
||||
continue
|
||||
}
|
||||
rpt.Repeat = append(rpt.Repeat, Repeat{
|
||||
Unit: STAR_SECOND,
|
||||
Value: uint32(i),
|
||||
}, Repeat{
|
||||
Unit: STAR_MINUTE,
|
||||
Value: uint32(i),
|
||||
})
|
||||
}
|
||||
/*
|
||||
for i := 0; i < 24; i++ {
|
||||
rpt.Repeat = append(rpt.Repeat, Repeat{
|
||||
Unit: STAR_HOUR,
|
||||
Value: uint32(i),
|
||||
})
|
||||
}
|
||||
|
||||
*/
|
||||
for i := 1; i < 7; i++ {
|
||||
rpt.Repeat = append(rpt.Repeat, Repeat{
|
||||
Unit: STAR_MONTH,
|
||||
Value: uint32(i),
|
||||
})
|
||||
}
|
||||
tk := StarTimer{
|
||||
base: time.Now(),
|
||||
repeat: []*Repeats{
|
||||
{
|
||||
Every: false,
|
||||
Repeat: rpt.Repeat,
|
||||
},
|
||||
},
|
||||
}
|
||||
base := tk.base
|
||||
for i := 0; i < 10; i++ {
|
||||
base = tk.parseNextDate(base, true)
|
||||
fmt.Println(base)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPrepareCron(t *testing.T) {
|
||||
tk := StarTimer{
|
||||
base: time.Now(),
|
||||
repeat: []*Repeats{
|
||||
{
|
||||
//*/3,5,6 */2,4,6 6 1-5 5
|
||||
Every: false,
|
||||
Repeat: []Repeat{
|
||||
{Unit: STAR_MINUTE, Value: 0}, {Unit: STAR_MINUTE, Value: 3}, {Unit: STAR_MINUTE, Value: 6}, {Unit: STAR_MINUTE, Value: 9}, {Unit: STAR_MINUTE, Value: 12}, {Unit: STAR_MINUTE, Value: 15}, {Unit: STAR_MINUTE, Value: 18}, {Unit: STAR_MINUTE, Value: 21},
|
||||
{Unit: STAR_MINUTE, Value: 24}, {Unit: STAR_MINUTE, Value: 27}, {Unit: STAR_MINUTE, Value: 30}, {Unit: STAR_MINUTE, Value: 33}, {Unit: STAR_MINUTE, Value: 36}, {Unit: STAR_MINUTE, Value: 39}, {Unit: STAR_MINUTE, Value: 42}, {Unit: STAR_MINUTE, Value: 45},
|
||||
{Unit: STAR_MINUTE, Value: 48}, {Unit: STAR_MINUTE, Value: 51}, {Unit: STAR_MINUTE, Value: 54}, {Unit: STAR_MINUTE, Value: 57}, {Unit: STAR_MINUTE, Value: 5},
|
||||
{Unit: STAR_HOUR, Value: 2}, {Unit: STAR_HOUR, Value: 4}, {Unit: STAR_HOUR, Value: 6}, {Unit: STAR_HOUR, Value: 8}, {Unit: STAR_HOUR, Value: 10}, {Unit: STAR_HOUR, Value: 12}, {Unit: STAR_HOUR, Value: 14}, {Unit: STAR_HOUR, Value: 16}, {Unit: STAR_HOUR, Value: 18}, {Unit: STAR_HOUR, Value: 20}, {Unit: STAR_HOUR, Value: 22}, {Unit: STAR_HOUR, Value: 0},
|
||||
{Unit: STAR_DAY, Value: 6},
|
||||
{Unit: STAR_MONTH, Value: 1}, {Unit: STAR_MONTH, Value: 2}, {Unit: STAR_MONTH, Value: 3}, {Unit: STAR_MONTH, Value: 4}, {Unit: STAR_MONTH, Value: 5},
|
||||
{Unit: STAR_WEEK, Value: 5},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
base := tk.base
|
||||
for i := 0; i < 10; i++ {
|
||||
base = tk.parseNextDate(base, true)
|
||||
fmt.Println(base)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPrepareCronSimple(t *testing.T) {
|
||||
tk := StarTimer{
|
||||
base: time.Now(),
|
||||
repeat: []*Repeats{
|
||||
{
|
||||
Every: false,
|
||||
Repeat: []Repeat{
|
||||
{Unit: STAR_MINUTE, Value: 0}, {Unit: STAR_MINUTE, Value: 3}, {Unit: STAR_MINUTE, Value: 6},
|
||||
{Unit: STAR_HOUR, Value: 2}, {Unit: STAR_HOUR, Value: 4}, {Unit: STAR_HOUR, Value: 6},
|
||||
{Unit: STAR_DAY, Value: 6},
|
||||
{Unit: STAR_MONTH, Value: 1}, {Unit: STAR_MONTH, Value: 5},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
base := tk.base
|
||||
for i := 0; i < 1; i++ {
|
||||
base = tk.parseNextDate(base, true)
|
||||
fmt.Println(base)
|
||||
fmt.Println("")
|
||||
}
|
||||
}
|
||||
|
151
timer.go
151
timer.go
@ -201,9 +201,14 @@ func (t *StarTimer) parseNextDate(base time.Time, isMock bool) time.Time {
|
||||
if len(dates) == 0 {
|
||||
return time.Time{}
|
||||
}
|
||||
now := time.Now().UnixNano()
|
||||
var bt int64
|
||||
if !isMock {
|
||||
bt = time.Now().UnixNano()
|
||||
} else {
|
||||
bt = base.UnixNano()
|
||||
}
|
||||
for _, v := range dates {
|
||||
if v.UnixNano() > now {
|
||||
if v.UnixNano() > bt {
|
||||
return v
|
||||
}
|
||||
}
|
||||
@ -211,54 +216,112 @@ func (t *StarTimer) parseNextDate(base time.Time, isMock bool) time.Time {
|
||||
}
|
||||
|
||||
func (t *StarTimer) parseStaticNextDate(base time.Time, r *Repeats) time.Time {
|
||||
target := base
|
||||
if !r.Every { //固定日期
|
||||
var targets []time.Time
|
||||
var uniqueRepeat [][]Repeat
|
||||
selectMap := make(map[Unit][]Repeat)
|
||||
{
|
||||
for _, d := range r.Repeat {
|
||||
switch d.Unit {
|
||||
case STAR_SECOND:
|
||||
sub := int(d.Value) - target.Second()
|
||||
if sub < 0 {
|
||||
sub += 60
|
||||
selectMap[d.Unit] = append(selectMap[d.Unit], d)
|
||||
}
|
||||
for key, val := range selectMap {
|
||||
if key == STAR_WEEK {
|
||||
continue
|
||||
}
|
||||
defUnikey := make([][]Repeat, 0, 1024)
|
||||
for _, vs := range val {
|
||||
if len(uniqueRepeat) == 0 {
|
||||
defUnikey = append(defUnikey, []Repeat{vs})
|
||||
} else {
|
||||
for k := range uniqueRepeat {
|
||||
tmp := make([]Repeat, len(uniqueRepeat[k])+1)
|
||||
copy(tmp, append(uniqueRepeat[k], vs))
|
||||
defUnikey = append(defUnikey, tmp)
|
||||
}
|
||||
}
|
||||
target = target.Add(time.Second * time.Duration(sub))
|
||||
case STAR_MINUTE:
|
||||
sub := int(d.Value) - target.Minute()
|
||||
if sub < 0 {
|
||||
sub += 60
|
||||
}
|
||||
target = target.Add(time.Minute * time.Duration(sub))
|
||||
case STAR_HOUR:
|
||||
sub := int(d.Value) - target.Hour()
|
||||
if sub < 0 {
|
||||
sub += 24
|
||||
}
|
||||
target = target.Add(time.Hour * time.Duration(sub))
|
||||
case STAR_DAY:
|
||||
sub := int(d.Value) - target.Day()
|
||||
if sub >= 0 {
|
||||
target = target.Add(time.Hour * 24 * time.Duration(sub))
|
||||
continue
|
||||
}
|
||||
target = time.Date(target.Year(), target.Month()+1, int(d.Value), target.Hour(), target.Minute(), target.Second(), 0, target.Location())
|
||||
case STAR_MONTH:
|
||||
sub := int(d.Value) - int(target.Month())
|
||||
if sub < 0 {
|
||||
sub += 12
|
||||
}
|
||||
target = target.AddDate(0, sub, 0)
|
||||
case STAR_YEAR:
|
||||
sub := int(d.Value) - int(target.Year())
|
||||
if sub < 0 {
|
||||
return time.Date(0, 0, 0, 0, 0, 0, 0, nil)
|
||||
}
|
||||
target = target.AddDate(sub, 0, 0)
|
||||
}
|
||||
if len(defUnikey) > 0 {
|
||||
uniqueRepeat = defUnikey
|
||||
}
|
||||
}
|
||||
}
|
||||
if target == base {
|
||||
return time.Time{}
|
||||
for _, task := range uniqueRepeat {
|
||||
sort.SliceStable(task, func(i, j int) bool {
|
||||
return task[i].Unit < task[j].Unit
|
||||
})
|
||||
target := base
|
||||
if !r.Every { //固定日期
|
||||
for _, d := range task {
|
||||
switch d.Unit {
|
||||
case STAR_SECOND:
|
||||
sub := int(d.Value) - target.Second()
|
||||
if sub < 0 {
|
||||
sub += 60
|
||||
}
|
||||
target = target.Add(time.Second * time.Duration(sub))
|
||||
case STAR_MINUTE:
|
||||
sub := int(d.Value) - target.Minute()
|
||||
if sub < 0 {
|
||||
sub += 60
|
||||
}
|
||||
target = target.Add(time.Minute * time.Duration(sub))
|
||||
case STAR_HOUR:
|
||||
sub := int(d.Value) - target.Hour()
|
||||
if sub < 0 {
|
||||
sub += 24
|
||||
}
|
||||
target = target.Add(time.Hour * time.Duration(sub))
|
||||
case STAR_DAY:
|
||||
sub := int(d.Value) - target.Day()
|
||||
if sub >= 0 {
|
||||
target = target.Add(time.Hour * 24 * time.Duration(sub))
|
||||
continue
|
||||
}
|
||||
target = time.Date(target.Year(), target.Month()+1, int(d.Value), target.Hour(), target.Minute(), target.Second(), 0, target.Location())
|
||||
case STAR_MONTH:
|
||||
sub := int(d.Value) - int(target.Month())
|
||||
if sub < 0 {
|
||||
sub += 12
|
||||
}
|
||||
target = target.AddDate(0, sub, 0)
|
||||
case STAR_YEAR:
|
||||
sub := int(d.Value) - int(target.Year())
|
||||
if sub < 0 {
|
||||
continue
|
||||
}
|
||||
target = target.AddDate(sub, 0, 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if target == base {
|
||||
continue
|
||||
}
|
||||
targets = append(targets, target)
|
||||
|
||||
}
|
||||
return target
|
||||
sort.SliceStable(targets, func(i, j int) bool {
|
||||
return targets[i].UnixNano() < targets[j].UnixNano()
|
||||
})
|
||||
for k, v := range targets {
|
||||
if v.After(base) {
|
||||
targets = targets[k:]
|
||||
break
|
||||
}
|
||||
}
|
||||
if val, ok := selectMap[STAR_WEEK]; ok {
|
||||
if len(targets) > 0 {
|
||||
for _, week := range val {
|
||||
if int(targets[0].Weekday()) == int(week.Value) {
|
||||
return targets[0]
|
||||
}
|
||||
}
|
||||
return t.parseStaticNextDate(targets[0].Add(time.Hour*24), r)
|
||||
}
|
||||
}
|
||||
if len(targets) > 0 {
|
||||
return targets[0]
|
||||
}
|
||||
return time.Time{}
|
||||
}
|
||||
|
||||
func (t *StarTimer) parseEveryNextDate(target time.Time, r *Repeats, isMock bool) []time.Time {
|
||||
|
Loading…
x
Reference in New Issue
Block a user