Skip to content

CronExpression skips days on midnight DST gap#36865

Open
zmovo wants to merge 1 commit into
spring-projects:mainfrom
zmovo:fix-cron-dst-midnight-gap-36859
Open

CronExpression skips days on midnight DST gap#36865
zmovo wants to merge 1 commit into
spring-projects:mainfrom
zmovo:fix-cron-dst-midnight-gap-36859

Conversation

@zmovo
Copy link
Copy Markdown

@zmovo zmovo commented Jun 3, 2026

Fixes #36859.

By default, BitsCronField#nextOrSame delegates to nextSetBit(0) after rollForward, which assumes the field value in the new period starts at zero. When daylight saving creates a gap at the start of a period (for example, Africa/Cairo advancing from 00:00 to 01:00), the rolled-forward temporal lands on a non-zero field value and matching from zero can advance an entire period too far, causing CronExpression#next to skip the calendar day.

This PR searches for the next matching bit from the actual field value in the new period instead, falling back to zero only when no bit matches in that period.

This does not change the existing contract for cron times that fall inside a DST gap: those executions are still skipped rather than deferred or replayed after the transition. The fix only ensures that subsequent valid matches on the same calendar day are still calculated correctly.

It also adds a regression test in CronExpressionTests#daylightSaving for a every-two-hours expression across the Cairo spring-forward boundary.

After rollForward, BitsCronField always searched for the next
matching bit from zero. When daylight saving creates a gap at
the start of a period (e.g. Africa/Cairo), the temporal lands on
a non-zero field value and matching from zero could advance an
entire period too far, skipping the calendar day.

Search from the actual field value in the new period instead,
falling back to zero only when no bit matches in that period.

Closes spring-projectsgh-36859

Signed-off-by: arno <me@zmovo.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged or decided on label Jun 3, 2026
@zmovo zmovo force-pushed the fix-cron-dst-midnight-gap-36859 branch from c52c11f to ceb9cd9 Compare June 3, 2026 07:28
@bclozel bclozel added type: bug A general bug in: core Issues in core modules (aop, beans, core, context, expression) and removed status: waiting-for-triage An issue we've not yet triaged or decided on labels Jun 3, 2026
@bclozel bclozel added this to the 7.0.x milestone Jun 3, 2026
@bclozel bclozel changed the title Fix CronExpression day skip on midnight DST gap CronExpression skips days on midnight DST gap Jun 3, 2026
@zmovo

This comment was marked as outdated.

@sbrannen

This comment was marked as outdated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

in: core Issues in core modules (aop, beans, core, context, expression) type: bug A general bug

Projects

None yet

Development

Successfully merging this pull request may close these issues.

The time of daylight saving time parsed by CronExpression is completely skipped

4 participants