master
兔子 2 years ago
parent 441b552380
commit a8f7de6042

@ -2,6 +2,7 @@ package startimer
import ( import (
"context" "context"
"encoding/json"
"errors" "errors"
"sort" "sort"
"sync" "sync"
@ -96,6 +97,40 @@ func (t *StarTimer) NextTimer() time.Time {
return t.nextDate return t.nextDate
} }
func (t *StarTimer) NextTimerAfterDate(date time.Time) time.Time {
return t.parseNextDate(date, true)
}
func (t *StarTimer) ExportRepeats() (string, error) {
var rep []Repeats
for _, r := range t.repeat {
rep = append(rep, *r)
}
data, err := json.Marshal(rep)
if err != nil {
return "", err
}
return string(data), nil
}
func (t *StarTimer) ImportRepeats(r string) error {
t.mu.Lock()
defer t.mu.Unlock()
if t.running {
return errors.New("coonot import repeats to already running timer")
}
var rep []Repeats
err := json.Unmarshal([]byte(r), &rep)
if err != nil {
return err
}
t.repeat = make([]*Repeats, 0, len(rep))
for _, v := range rep {
t.repeat = append(t.repeat, &v)
}
return nil
}
func (t *StarTimer) BaseDate() time.Time { func (t *StarTimer) BaseDate() time.Time {
return t.base return t.base
} }
@ -113,7 +148,7 @@ func (t *StarTimer) Run() error {
if t.running { if t.running {
return nil return nil
} }
t.nextDate = t.parseNextDate(t.base) t.nextDate = t.parseNextDate(time.Now(), false)
if t.nextDate.Before(time.Now()) { if t.nextDate.Before(time.Now()) {
return errors.New("Invalid Timer Options,Please Check") return errors.New("Invalid Timer Options,Please Check")
} }
@ -127,7 +162,7 @@ func (t *StarTimer) Run() error {
t.mu.Unlock() t.mu.Unlock()
select { select {
case <-t.timer.C: case <-t.timer.C:
t.nextDate = t.parseNextDate(t.nextDate) t.nextDate = t.parseNextDate(t.nextDate, false)
if t.nextDate.Before(now) { if t.nextDate.Before(now) {
t.Stop() t.Stop()
} }
@ -145,7 +180,7 @@ func (t *StarTimer) Run() error {
return nil return nil
} }
func (t *StarTimer) parseNextDate(base time.Time) time.Time { func (t *StarTimer) parseNextDate(base time.Time, isMock bool) time.Time {
if len(t.repeat) == 0 { if len(t.repeat) == 0 {
return time.Time{} return time.Time{}
} }
@ -155,7 +190,7 @@ func (t *StarTimer) parseNextDate(base time.Time) time.Time {
continue continue
} }
if d.Every { if d.Every {
dates = append(dates, t.parseEveryNextDate(base, d)...) dates = append(dates, t.parseEveryNextDate(base, d, isMock)...)
} else { } else {
dates = append(dates, t.parseStaticNextDate(base, d)) dates = append(dates, t.parseStaticNextDate(base, d))
} }
@ -226,13 +261,15 @@ func (t *StarTimer) parseStaticNextDate(base time.Time, r *Repeats) time.Time {
return target return target
} }
func (t *StarTimer) parseEveryNextDate(target time.Time, r *Repeats) []time.Time { func (t *StarTimer) parseEveryNextDate(target time.Time, r *Repeats, isMock bool) []time.Time {
var res []time.Time var res []time.Time
if r.Every { //定期日期 if r.Every { //定期日期
for idx, d := range r.Repeat { for idx, d := range r.Repeat {
if d.baseDate.Unix() == -62135596800 { if d.baseDate.Unix() == -62135596800 {
d.baseDate = t.base d.baseDate = t.base
r.Repeat[idx] = d if !isMock {
r.Repeat[idx] = d
}
} }
if d.baseDate.After(target) { if d.baseDate.After(target) {
res = append(res, d.baseDate) res = append(res, d.baseDate)
@ -243,7 +280,9 @@ func (t *StarTimer) parseEveryNextDate(target time.Time, r *Repeats) []time.Time
for { for {
d.baseDate = d.baseDate.Add(time.Second * time.Duration(int(d.Value))) d.baseDate = d.baseDate.Add(time.Second * time.Duration(int(d.Value)))
if d.baseDate.After(target) { if d.baseDate.After(target) {
r.Repeat[idx] = d if !isMock {
r.Repeat[idx] = d
}
break break
} }
} }
@ -252,7 +291,9 @@ func (t *StarTimer) parseEveryNextDate(target time.Time, r *Repeats) []time.Time
for { for {
d.baseDate = d.baseDate.Add(time.Minute * time.Duration(int(d.Value))) d.baseDate = d.baseDate.Add(time.Minute * time.Duration(int(d.Value)))
if d.baseDate.After(target) { if d.baseDate.After(target) {
r.Repeat[idx] = d if !isMock {
r.Repeat[idx] = d
}
break break
} }
} }
@ -261,7 +302,9 @@ func (t *StarTimer) parseEveryNextDate(target time.Time, r *Repeats) []time.Time
for { for {
d.baseDate = d.baseDate.Add(time.Hour * time.Duration(int(d.Value))) d.baseDate = d.baseDate.Add(time.Hour * time.Duration(int(d.Value)))
if d.baseDate.After(target) { if d.baseDate.After(target) {
r.Repeat[idx] = d if !isMock {
r.Repeat[idx] = d
}
break break
} }
} }
@ -270,7 +313,9 @@ func (t *StarTimer) parseEveryNextDate(target time.Time, r *Repeats) []time.Time
for { for {
d.baseDate = d.baseDate.Add(time.Hour * 24 * time.Duration(int(d.Value))) d.baseDate = d.baseDate.Add(time.Hour * 24 * time.Duration(int(d.Value)))
if d.baseDate.After(target) { if d.baseDate.After(target) {
r.Repeat[idx] = d if !isMock {
r.Repeat[idx] = d
}
break break
} }
} }
@ -279,7 +324,9 @@ func (t *StarTimer) parseEveryNextDate(target time.Time, r *Repeats) []time.Time
for { for {
d.baseDate = d.baseDate.AddDate(0, int(d.Value), 0) d.baseDate = d.baseDate.AddDate(0, int(d.Value), 0)
if d.baseDate.After(target) { if d.baseDate.After(target) {
r.Repeat[idx] = d if !isMock {
r.Repeat[idx] = d
}
break break
} }
} }
@ -288,7 +335,9 @@ func (t *StarTimer) parseEveryNextDate(target time.Time, r *Repeats) []time.Time
for { for {
d.baseDate = d.baseDate.AddDate(int(d.Value), 0, 0) d.baseDate = d.baseDate.AddDate(int(d.Value), 0, 0)
if d.baseDate.After(target) { if d.baseDate.After(target) {
r.Repeat[idx] = d if !isMock {
r.Repeat[idx] = d
}
break break
} }
} }

@ -18,14 +18,14 @@ const (
) )
type Repeats struct { type Repeats struct {
Repeat []Repeat Repeat []Repeat `json:"repeat"`
Every bool // false=static true=every Every bool `json:"every"` // false=static true=every
} }
type Repeat struct { type Repeat struct {
Unit Unit Unit Unit `json:"unit"`
baseDate time.Time baseDate time.Time
Value uint32 Value uint32 `json:"value"`
} }
type StarTimer struct { type StarTimer struct {
@ -46,8 +46,8 @@ type TimerOption struct {
idx uint8 idx uint8
repeats *Repeats repeats *Repeats
tasks func() tasks func()
date time.Time date time.Time
repeat Repeat repeat Repeat
} }
func WithRepeats(r *Repeats) TimerOptions { func WithRepeats(r *Repeats) TimerOptions {

Loading…
Cancel
Save