package startimer import ( "context" "sync" "time" ) type Unit uint8 const ( STAR_SECOND Unit = iota STAR_MINUTE STAR_HOUR STAR_DAY STAR_MONTH STAR_WEEK STAR_YEAR ) type Repeats struct { Repeat []Repeat `json:"repeat"` Every bool `json:"every"` // false=static true=every } type Repeat struct { Unit Unit `json:"unit"` baseDate time.Time Value uint32 `json:"value"` } type StarTimer struct { base time.Time nextDate time.Time timer *time.Timer stopFn context.CancelFunc stopCtx context.Context mu *sync.RWMutex running bool repeat []*Repeats tasks []func() } type TimerOptions func(option *TimerOption) type TimerOption struct { idx uint8 repeats *Repeats tasks func() date time.Time repeat Repeat } func WithRepeats(r *Repeats) TimerOptions { return func(option *TimerOption) { option.idx = 1 option.repeats = r } } func WithRepeat(r Repeat) TimerOptions { return func(option *TimerOption) { option.idx = 4 option.repeat = r } } func WithTask(t func()) TimerOptions { return func(option *TimerOption) { option.idx = 2 option.tasks = t } } func WithStaticDate(t time.Time) TimerOptions { return func(option *TimerOption) { option.idx = 3 option.date = t } } func NewRepeat(baseTime time.Time, unit Unit, val uint32) Repeat { return Repeat{ Unit: unit, baseDate: baseTime, Value: val, } } func NextDayOfWeek(date time.Time, weekDay int) time.Time { sub := weekDay - int(date.Weekday()) if sub <= 0 { sub += 7 } return date.Add(time.Hour * 24 * time.Duration(sub)) }