Java › Java Date & Time API (java.time)

How would you implement a recurring event scheduling system that correctly handles both fixed-instant recurrence (every exactly 24 hours) and calendar-based recurrence (every day at 9 AM local time), given these have meaningfully different behavior across DST transitions?

Advanced

Answer

A fixed-instant recurrence (like 'run a health check every exactly 3600 seconds') should be modeled using Instant arithmetic with a Duration, guaranteeing a truly constant, unwavering interval regardless of any DST transitions that might occur in some observer's local timezone; a calendar-based recurrence (like 'send a daily digest email at 9 AM local time for each recipient') should instead be modeled using ZonedDateTime arithmetic with plusDays(), which correctly preserves the same LOCAL wall-clock time (9 AM) across a DST transition, even though the actual UTC instant corresponding to that local 9 AM shifts by an hour during the transition -- choosing the wrong model for a given recurrence type produces genuinely incorrect behavior (a 'daily 9 AM' notification arriving at 8 AM or 10 AM local time on the day of a DST transition if implemented with fixed Instant/Duration arithmetic instead of ZonedDateTime).
// Fixed-instant recurrence: exactly 24 hours, regardless of any DST transition
Instant nextHealthCheck = lastCheck.plus(Duration.ofHours(24));

// Calendar-based recurrence: same LOCAL time each day, correctly adjusting across DST
ZonedDateTime nextDigestEmail = lastDigest.plusDays(1);  // still 9:00 AM local time, even across a DST transition
// Using Duration.ofDays(1) added to an Instant here would be WRONG -- it would drift by an hour on DST transition days
Real-world example A notification scheduling system initially implemented daily reminders using Instant.plus(Duration.ofDays(1)) and received user complaints that reminders arrived an hour off schedule on the specific days each year when DST transitions occurred, fixed by switching to ZonedDateTime.plusDays(1) which correctly preserves the intended local wall-clock time across those transitions.

Common follow-ups: How would you test this specific DST-crossing behavior reliably in an automated test suite, given DST transitions only occur on specific calendar dates?;What's the correct modeling choice for a recurrence that should happen 'every 2 weeks at the same local time' -- fixed-instant or calendar-based?