-
Notifications
You must be signed in to change notification settings - Fork 122
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
GetNextOccurrence calculated incorrect when switching from DST #71
Comments
Hello @redstarty Thank you for the description and examples. Let me explain the logic behind handling DST transitions in Cronos. To avoid messing things up, Cronos splits the timeline into Daylight Time → Ambiguous Time → Standard Time during transitions in Autumn, and handles the timeline differently for different types of cron expressions. Interval-based expressions, like When second, minute or hour field do contain stars, steps or ranges, then everything works as usually, since we expect that our cron expression will be triggered each 30 minutes, without any differences for each interval. Non-interval-based expressions, like However, when second, minute or hour field don't contain stars, steps or ranges, we usually don't expect there will be multiple executions during daylight saving time transitions, since for the remaining part of the year they are executing only once per week. So, these expressions are mapped only to the Daylight Time part of the Ambiguous time, and aren't mapped to the Standard Time part of the Ambiguous time, so the whole range from 1:00 to 2:00 AM UTC is ignored to avoid having duplicate executions for these expressions, and this is by design. But if you run the following lines, where var cron = CronExpression.Parse("0 0 2 * * 0", CronFormat.Standard | CronFormat.IncludeSeconds);
var requestedAt = new DateTime(2024, 10, 26, 23, 30, 0, DateTimeKind.Utc);
var timeZone = TimeZoneInfo.FindSystemTimeZoneById("W. Europe Standard Time");
var nextOccurrence = cron.GetNextOccurrence(requestedAt, timeZone, inclusive: false);
Assert.NotNull(nextOccurrence);
Assert.Equal(requestedAt.AddMinutes(30), nextOccurrence.Value); |
Thanks a lot for the clear explanation and examples. As I understand, a problem with my use case could happen only when the next occurrence is requested during the Ambiguous time. The probability of which... well, not that high. Would you recommend any way to clearly understand if now is the Ambiguous time? In any case, this issue can be closed. Thanks again. |
On the contrary, this behavior will help you to avoid having unwanted second recurring job invocation during the DST transition in Hangfire. So there will be the following invocations around that date, once per week:
However, if we disable such behavior, we'll get two invocations on Oct 27, and usually such a behavior leads to unexpected errors.
|
Alas, for my use case it would be better to actually have this extra invocation during the DST transition in Hangfire - to make sure that if user wants something to happen at 2:00 in their time zone, than it will actually happen at 2:00, no matter if he requested it beforehand or at 00:30 UTC that day. And extra invocation won't be a problem for me. |
That's why I used the word |
Hello there!
This issue was initially spotted using Hangfire jobs scheduler, but I managed to investigate it to the following point:
So, imagine we have a cron
0 0 2 * * 0
(run at 2:00 each Sunday) and a specific time zone W. Europe Standard Time (supports DST, UTC+1 when non-DST, UTC+2 when DST). And Sunday 27th of October is the day when we move from DST to non-DST which leads to time 02:00 in this timezone happen twice (at 00:00 UTC and 01:00 UTC).We request next occurrence exactly at 00:30 UTC and expect it to be 01:00 UTC time, but it is actually skipped.
Here, I draw a picture:
And here is a code to reproduce it:
The code output is
2024-11-03T01:00:00.0000000Z
- next week. And I would expect it to be2024-10-27T01:00:00.0000000Z
The text was updated successfully, but these errors were encountered: