cron icon indicating copy to clipboard operation
cron copied to clipboard

schedule timezone local.

Open butalso opened this issue 4 years ago • 4 comments

if the schedules timezone not specify, it's local timezone. but the code doesn't convert the t to the schedule timezone. and compare time below with schedule and t.

// Convert the given time into the schedule's timezone, if one is specified.
	// Save the original timezone so we can convert back after we find a time.
	// Note that schedules without a time zone specified (time.Local) are treated
	// as local to the time provided.
	origLocation := t.Location()
	loc := s.Location
	if loc == time.Local {
		loc = t.Location()
	}
	if s.Location != time.Local {
		t = t.In(s.Location)
	}

butalso avatar Mar 05 '20 01:03 butalso

Thank you for the report. Can you provide a test case that demonstrates the issue?

robfig avatar Apr 14 '20 17:04 robfig

Hello, I met the same issue, I think. Here is the test reproducing the issue:

func TestCronTimezone(t *testing.T) {

	loc, _ := time.LoadLocation("Europe/Paris")
	cronProcess := cron.New(cron.WithLocation(loc))

	entryID, _ := cronProcess.AddFunc("0 6 * * *", func() {
		log.Printf("Cron job : %s", time.Now())
	})
	cronProcess.Start()

	now := time.Date(2020, 4, 23, 5, 30, 0, 0, time.UTC)
	// In "Europe/Paris" timezone, equals to 2020-04-23T07:30:00
	nowInLoc := now.In(loc)
	if !now.Equal(nowInLoc) {
		t.Errorf("Should not happen, because dates are the same")
	}

	entry := cronProcess.Entry(entryID)
	next := entry.Schedule.Next(now)
	nextInLoc := entry.Schedule.Next(nowInLoc)

	if !next.Equal(nextInLoc) {
		t.Errorf("Should not happen: next %s, next in location %s", next, nextInLoc)
	}
}

And the result:

Should not happen: next 2020-04-23 06:00:00 +0000 UTC, next in location 2020-04-24 06:00:00 +0200 CEST

We can see the "next" time is on two different days, whereas the "now" and "nowInLoc" dates are equals.

renomarx avatar Apr 23 '20 08:04 renomarx

Found a similar issue:



func Test(t *testing.T) {
	schedule, err := cron.ParseStandard("TZ=America/Los_Angeles 0 2 * * 0")
	require.NoError(t, err)

	zone, err := time.LoadLocation("America/Los_Angeles")
	require.NoError(t, err)

	now := time.Date(2022, 3, 1, 0, 0, 0, 0, zone)

	expectedNext := time.Date(2022, 3, 6, 2, 0, 0, 0, zone)
	nextSchedule := schedule.Next(now)
	assert.Equal(t, expectedNext.String(), nextSchedule.String())

	expectedNextNext := time.Date(2022, 3, 13, 2, 0, 0, 0, zone)
	nextNextSchedule := schedule.Next(nextSchedule)
	assert.Equal(t, expectedNextNext.String(), nextNextSchedule.String()) // Will fail, time will be 2022/3/20 02:00:00
}

drshriveer avatar Apr 02 '22 00:04 drshriveer

On closer inspection the issue I'm referring to may be because of daylight savings time. I chose the times above for an unrelated test completely by accident apparently but in 2022, Daylight savings begins on 03/13 02:00 (moving the clock to 03:00), so 02:00 is actually not a reachable time. Sadly I can't specify a PST vs PDT, only "America/Los_Angels"... A cautionary tale I suppose.

drshriveer avatar Apr 04 '22 16:04 drshriveer