fix: NextTickAfter stuck on DST fall-back (#50)#68
Conversation
bump() for hour/minute reconstructs via time.Date, which picks the first occurrence of an ambiguous wall-clock hour. The bump advances 0s in UTC and bumpUntilDue spins until its iter limit. Assert the bump moved forward; correct with +1h if not. Fixes adhocore#50.
|
Hi @adhocore ! Would appreciate any feedback and a release after fix if possible - this gets a nasty bug around DST, added some tests you can run to prove correctness as well or come up with a good suggestion yourself |
|
thank you very much. checking this shortly, for now just triggered the github action pipelines. |
| ref = time.Date(minTime.Year(), minTime.Month(), minTime.Day(), minTime.Hour(), minTime.Minute(), 0, 0, loc) | ||
| next := time.Date(minTime.Year(), minTime.Month(), minTime.Day(), minTime.Hour(), minTime.Minute(), 0, 0, loc) | ||
| if !next.After(ref) { | ||
| next = next.Add(time.Hour) |
There was a problem hiding this comment.
is it to be advanced by a minute or hour?
There was a problem hiding this comment.
I think it should be an hour. For minutely advance on the DST boundary, when we advance from 1:59 back to 1:00 on day of US DST, we need to advance a full hour to be correct
There was a problem hiding this comment.
Hi @adhocore! Did you get the chance to take a look?
There was a problem hiding this comment.
hello, is there an issue if we advance by 15min? I think timezones are in gaps of 15min, 30min and 1 or more hours. so 15min seem to cover them all.
There was a problem hiding this comment.
I think the issue is this line
ref = time.Date(minTime.Year(), minTime.Month(), minTime.Day(), minTime.Hour(), minTime.Minute(), 0, 0, loc)
shifts the UTC instant ~60min backwards around DST. Example:
From ref = 01:59 EDT (UTC 05:59Z):
ref + 1m → UTC 06:00Z = 01:00 EST (real next minute)
time.Date(...1, 0, …) → UTC 05:00Z = 01:00 EDT (first occurrence wins → -60min in UTC)
With +15min: next = UTC 05:15Z = 01:15 EDT. Still 44min before ref, but bump returns it. bumpUntilDue then walks 01:16 → 01:17 → … → 01:59 EDT, hits the same boundary, collapses again, bounces to 01:15, and keeps looping
With +1h: next = UTC 06:00Z = 01:00 EST — past the ambiguous region, walker proceeds normally.
The correction has to be ≥ the shift, open to some other ideas though
|
I just ran into this as well, looking at the implementation of |
|
I think that might break non whole-hour-offset zones (take nepal time for example) since it's rounding the UTC instant |
|
hi guys thanks for participation, and special thanks to @azhang-kal for pr. it's been merged and released in v1.20.0 |
Fixes #50.
NextTickAfterspins / returns invalid ticks during DST fall-back when the schedule skips the ambiguous wall-clock hour. Repro:"0 */8 * * *"from2024-11-03 00:30 EDTinAmerica/New_Yorkreturns01:00 EDT(whichIsDuethen says false on), and the next call errors with"tried so hard".bump()for the hour case reconstructs viatime.Date(...), which picks the first occurrence of an ambiguous wall hour — same hour asref, so the bump advances 0s in UTC andbumpUntilDuespins. Same shape in the minute case.Fix asserts the bump moved forward and corrects with
+1hif not.Scoped to hour + minute only since those are the cases that fire in any DST zone. Day/month/year reconstruct at midnight and would only be affected in midnight-DST zones — happy to follow up with a defense-in-depth pass if you want.
Test added covering the ambiguous-hour skip and the original
"tried so hard"repro from #50.