Skip to content

Commit 2fc07a4

Browse files
committed
# Conflicts: # cron_test.go
2 parents 7f3990a + 9585fd5 commit 2fc07a4

File tree

5 files changed

+399
-104
lines changed

5 files changed

+399
-104
lines changed

cron.go

+17-4
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ type Cron struct {
1919
snapshot chan []*Entry
2020
running bool
2121
ErrorLog *log.Logger
22+
location *time.Location
2223
}
2324

2425
// Job is an interface for submitted cron jobs.
@@ -74,15 +75,21 @@ func (s byTime) Less(i, j int) bool {
7475
return s[i].Next.Before(s[j].Next)
7576
}
7677

77-
// New returns a new Cron job runner.
78+
// New returns a new Cron job runner, in the Local time zone.
7879
func New() *Cron {
80+
return NewWithLocation(time.Now().Location())
81+
}
82+
83+
// NewWithLocation returns a new Cron job runner.
84+
func NewWithLocation(location *time.Location) *Cron {
7985
return &Cron{
8086
entries: nil,
8187
add: make(chan *Entry),
8288
stop: make(chan struct{}),
8389
snapshot: make(chan []*Entry),
8490
running: false,
8591
ErrorLog: nil,
92+
location: location,
8693
}
8794
}
8895

@@ -131,6 +138,11 @@ func (c *Cron) Entries() []*Entry {
131138
return c.entrySnapshot()
132139
}
133140

141+
// Location gets the time zone location
142+
func (c *Cron) Location() *time.Location {
143+
return c.location
144+
}
145+
134146
// Start the cron scheduler in its own go-routine, or no-op if already started.
135147
func (c *Cron) Start() {
136148
if c.running {
@@ -156,7 +168,7 @@ func (c *Cron) runWithRecovery(j Job) {
156168
// access to the 'running' state variable.
157169
func (c *Cron) run() {
158170
// Figure out the next activation times for each entry.
159-
now := time.Now().Local()
171+
now := time.Now().In(c.location)
160172
for _, entry := range c.entries {
161173
entry.Next = entry.Schedule.Next(now)
162174
}
@@ -177,6 +189,7 @@ func (c *Cron) run() {
177189
timer := time.NewTimer(effective.Sub(now))
178190
select {
179191
case now = <-timer.C:
192+
now = now.In(c.location)
180193
// Run every entry whose next time was this effective time.
181194
for _, e := range c.entries {
182195
if e.Next != effective {
@@ -191,7 +204,7 @@ func (c *Cron) run() {
191204

192205
case newEntry := <-c.add:
193206
c.entries = append(c.entries, newEntry)
194-
newEntry.Next = newEntry.Schedule.Next(time.Now().Local())
207+
newEntry.Next = newEntry.Schedule.Next(time.Now().In(c.location))
195208

196209
case <-c.snapshot:
197210
c.snapshot <- c.entrySnapshot()
@@ -202,7 +215,7 @@ func (c *Cron) run() {
202215
}
203216

204217
// 'now' should be updated after newEntry and snapshot cases.
205-
now = time.Now().Local()
218+
now = time.Now().In(c.location)
206219
timer.Stop()
207220
}
208221
}

cron_test.go

+31-4
Original file line numberDiff line numberDiff line change
@@ -219,19 +219,46 @@ func TestRunningMultipleSchedules(t *testing.T) {
219219
// Test that the cron is run in the local time zone (as opposed to UTC).
220220
func TestLocalTimezone(t *testing.T) {
221221
wg := &sync.WaitGroup{}
222-
wg.Add(1)
222+
wg.Add(2)
223223

224224
now := time.Now().Local()
225-
spec := fmt.Sprintf("%d %d %d %d %d ?",
226-
now.Second()+1, now.Minute(), now.Hour(), now.Day(), now.Month())
225+
spec := fmt.Sprintf("%d,%d %d %d %d %d ?",
226+
now.Second()+1, now.Second()+2, now.Minute(), now.Hour(), now.Day(), now.Month())
227227

228228
cron := New()
229229
cron.AddFunc("", spec, func() { wg.Done() })
230230
cron.Start()
231231
defer cron.Stop()
232232

233233
select {
234-
case <-time.After(ONE_SECOND):
234+
case <-time.After(ONE_SECOND * 2):
235+
t.FailNow()
236+
case <-wait(wg):
237+
}
238+
}
239+
240+
// Test that the cron is run in the given time zone (as opposed to local).
241+
func TestNonLocalTimezone(t *testing.T) {
242+
wg := &sync.WaitGroup{}
243+
wg.Add(2)
244+
245+
loc, err := time.LoadLocation("Atlantic/Cape_Verde")
246+
if err != nil {
247+
fmt.Printf("Failed to load time zone Atlantic/Cape_Verde: %+v", err)
248+
t.Fail()
249+
}
250+
251+
now := time.Now().In(loc)
252+
spec := fmt.Sprintf("%d,%d %d %d %d %d ?",
253+
now.Second()+1, now.Second()+2, now.Minute(), now.Hour(), now.Day(), now.Month())
254+
255+
cron := NewWithLocation(loc)
256+
cron.AddFunc("", spec, func() { wg.Done() })
257+
cron.Start()
258+
defer cron.Stop()
259+
260+
select {
261+
case <-time.After(ONE_SECOND * 2):
235262
t.FailNow()
236263
case <-wait(wg):
237264
}

0 commit comments

Comments
 (0)