Files
geo/server/internal/shared/schedule/runtime.go
T

69 lines
1.3 KiB
Go
Raw Normal View History

package schedule
import (
"fmt"
"strings"
"time"
cron "github.com/robfig/cron/v3"
)
var cronParser = cron.NewParser(
cron.SecondOptional |
cron.Minute |
cron.Hour |
cron.Dom |
cron.Month |
cron.Dow |
cron.Descriptor,
)
func Parse(cronExpr string) (cron.Schedule, error) {
trimmed := strings.TrimSpace(cronExpr)
if trimmed == "" {
return nil, fmt.Errorf("cron expression is required")
}
schedule, err := cronParser.Parse(trimmed)
if err != nil {
return nil, fmt.Errorf("parse cron expression %q: %w", trimmed, err)
}
return schedule, nil
}
func ComputeNextRun(cronExpr string, startAt, endAt *time.Time, now time.Time) (*time.Time, error) {
schedule, err := Parse(cronExpr)
if err != nil {
return nil, err
}
notBefore := now.In(time.Local)
if startAt != nil {
start := startAt.In(time.Local)
if start.After(notBefore) {
notBefore = start
}
}
next := schedule.Next(notBefore.Add(-time.Nanosecond)).Round(0)
if next.IsZero() {
return nil, nil
}
if endAt != nil && next.After(endAt.In(time.Local)) {
return nil, nil
}
return &next, nil
}
func IsRunAllowed(runAt time.Time, startAt, endAt *time.Time) bool {
runAt = runAt.In(time.Local)
if startAt != nil && runAt.Before(startAt.In(time.Local)) {
return false
}
if endAt != nil && runAt.After(endAt.In(time.Local)) {
return false
}
return true
}