Skip to content

Port DST fall-back infinite trigger fix to 3.x (#2865)#2885

Merged
lahma merged 1 commit into
3.xfrom
port/dst-fallback-fix-3x
Mar 8, 2026
Merged

Port DST fall-back infinite trigger fix to 3.x (#2865)#2885
lahma merged 1 commit into
3.xfrom
port/dst-fallback-fix-3x

Conversation

@lahma

@lahma lahma commented Mar 8, 2026

Copy link
Copy Markdown
Member

Summary

Changes

  • src/Quartz/CronExpression.cs — Added using System.Linq and post-computation guard in GetTimeAfter to select the standard offset when the DST offset produces a result in the past
  • src/Quartz.Tests.Unit/DaylightSavingTimeTests.cs — Added regression test ShouldNotFireInfinitelyAfterDstFallBackTransition

Test plan

  • All existing DST tests pass (4/4 on both net10.0 and net472)
  • New regression test validates the Amsterdam/Oct 29 2023 scenario

🤖 Generated with Claude Code

When computing next fire time in CronExpression.GetTimeAfter, ambiguous
local times during DST fall-back transitions were assigned the DST
(summer) UTC offset, resulting in a UTC time that was before the input.
This caused triggers to always compute a next fire time in the past,
leading to infinite refires.

Fix: after computing the UTC result, if it falls before afterTimeUtc
and the local time is ambiguous, use the standard (non-DST) offset
instead — the minimum of the two ambiguous offsets — which corresponds
to the second (post-fallback) occurrence of the ambiguous local time.

Adds regression test ShouldNotFireInfinitelyAfterDstFallBackTransition
reproducing the Amsterdam/Europe scenario from the issue report.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
@sonarqubecloud

sonarqubecloud Bot commented Mar 8, 2026

Copy link
Copy Markdown

@lahma
lahma merged commit aa2add1 into 3.x Mar 8, 2026
9 checks passed
@lahma
lahma deleted the port/dst-fallback-fix-3x branch March 8, 2026 18:48
lahma added a commit that referenced this pull request Mar 29, 2026
…After (#2156)

The fall-back guard added in #2885 resolved the CronExpression DST issues
reported in #2156 and #2475. These tests lock in the fix with coverage for:
- IsSatisfiedBy during DST fall-back transition (exact #2156 reproduction)
- IsSatisfiedBy with UTC timezone during DST periods
- GetTimeAfter monotonicity across fall-back (90-minute walk)
- GetTimeAfter monotonicity across spring-forward (90-minute walk)
- Full minute-by-minute iteration through October across CET fall-back

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
lahma added a commit that referenced this pull request Mar 29, 2026
The fall-back guard added in #2885 resolved the CronExpression DST issues
reported in #2156 and #2475. These tests lock in the fix with coverage for:
- IsSatisfiedBy during DST fall-back transition (exact #2156 reproduction)
- IsSatisfiedBy with UTC timezone during DST periods
- GetTimeAfter monotonicity across fall-back (90-minute walk)
- GetTimeAfter monotonicity across spring-forward (90-minute walk)
- Full minute-by-minute iteration through October across CET fall-back

Co-authored-by: Claude Opus 4.6 (1M context) <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant