feat: add WithStartDateTimePast WithStartAt option (#882)

This commit is contained in:
John Roesler 2025-10-09 21:45:13 -05:00 committed by GitHub
parent 536410f98a
commit 6a30d6d8b9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 113 additions and 0 deletions

View File

@ -54,6 +54,7 @@ var (
ErrWithMonitorNil = errors.New("gocron: WithMonitor: monitor must not be nil")
ErrWithNameEmpty = errors.New("gocron: WithName: name must not be empty")
ErrWithStartDateTimePast = errors.New("gocron: WithStartDateTime: start must not be in the past")
ErrWithStartDateTimePastZero = errors.New("gocron: WithStartDateTime: start must not be zero")
ErrWithStopDateTimePast = errors.New("gocron: WithStopDateTime: end must not be in the past")
ErrStartTimeLaterThanEndTime = errors.New("gocron: WithStartDateTime: start must not be later than end")
ErrStopTimeEarlierThanStartTime = errors.New("gocron: WithStopDateTime: end must not be earlier than start")

View File

@ -1046,6 +1046,90 @@ func ExampleWithStartAt() {
// 9999-09-09 09:09:09.000000009 +0000 UTC
}
func ExampleWithStartDateTime() {
s, _ := gocron.NewScheduler()
defer func() { _ = s.Shutdown() }()
start := time.Date(9999, 9, 9, 9, 9, 9, 9, time.UTC)
j, _ := s.NewJob(
gocron.DurationJob(
time.Second,
),
gocron.NewTask(
func(one string, two int) {
fmt.Printf("%s, %d", one, two)
},
"one", 2,
),
gocron.WithStartAt(
gocron.WithStartDateTime(start),
),
)
s.Start()
next, _ := j.NextRun()
fmt.Println(next)
_ = s.StopJobs()
// Output:
// 9999-09-09 09:09:09.000000009 +0000 UTC
}
func ExampleWithStartDateTimePast() {
s, _ := gocron.NewScheduler()
defer func() { _ = s.Shutdown() }()
start := time.Now().Add(-time.Minute)
j, _ := s.NewJob(
gocron.DurationJob(
time.Second,
),
gocron.NewTask(
func(one string, two int) {
fmt.Printf("%s, %d", one, two)
},
"one", 2,
),
gocron.WithStartAt(
gocron.WithStartDateTimePast(start),
),
)
s.Start()
time.Sleep(100 * time.Millisecond)
_, _ = j.NextRun()
_ = s.StopJobs()
}
func ExampleWithStartImmediately() {
s, _ := gocron.NewScheduler()
defer func() { _ = s.Shutdown() }()
j, _ := s.NewJob(
gocron.DurationJob(
time.Second,
),
gocron.NewTask(
func(one string, two int) {
fmt.Printf("%s, %d", one, two)
},
"one", 2,
),
gocron.WithStartAt(
gocron.WithStartImmediately(),
),
)
s.Start()
_, _ = j.NextRun()
_ = s.StopJobs()
}
func ExampleWithStopTimeout() {
_, _ = gocron.NewScheduler(
gocron.WithStopTimeout(time.Second * 5),

20
job.go
View File

@ -718,6 +718,26 @@ func WithStartDateTime(start time.Time) StartAtOption {
}
}
// WithStartDateTimePast sets the first date & time at which the job should run
// from a time in the past. This is useful when you want to backdate
// the start time of a job to a time in the past, for example
// if you want to start a job from a specific date in the past
// and have it run on its schedule from then.
// The start time can be in the past, but not zero.
// If the start time is in the future, it behaves the same as WithStartDateTime.
func WithStartDateTimePast(start time.Time) StartAtOption {
return func(j *internalJob, _ time.Time) error {
if start.IsZero() {
return ErrWithStartDateTimePastZero
}
if !j.stopTime.IsZero() && j.stopTime.Before(start) {
return ErrStartTimeLaterThanEndTime
}
j.startTime = start
return nil
}
}
// WithStopAt sets the option for stopping the job from running
// after the specified time.
func WithStopAt(option StopAtOption) JobOption {

View File

@ -1004,6 +1004,14 @@ func TestScheduler_NewJobErrors(t *testing.T) {
[]JobOption{WithStartAt(WithStartDateTime(time.Now().Add(-time.Second)))},
ErrWithStartDateTimePast,
},
{
"WithStartDateTimePast is zero",
DurationJob(
time.Second,
),
[]JobOption{WithStartAt(WithStartDateTimePast(time.Time{}))},
ErrWithStartDateTimePastZero,
},
{
"WithStartDateTime is later than the end",
DurationJob(