recurring-events-time-zones-hardest-problem-calendar

Recurring Events and Time Zones: The Hardest Problem in Calendar Software

•5 min read
Recurring Events and Time Zones: The Hardest Problem in Calendar Software

Recurring Events and Time Zones: The Hardest Problem in Calendar Software

Ask any calendar engineer what the hardest problem in their domain is, and you will get the same answer: recurring events across time zones.

A single meeting is easy. Store a start time, an end time, and a time zone. Done. But a meeting that repeats every week, forever, across users in different time zones, through daylight saving transitions, over years of rule changes — that is where calendars break.

This guide explains why recurring events are so hard and how the industry handles them.

Use the free time zone converter here →


The Short Answer: Why Recurrence Is Hard

The difficulty comes from a collision between two ideas: recurrence rules (which repeat in calendar terms) and time zones (which shift in clock terms). When these two interact, especially across DST, the results are ambiguous or contradictory.

Problem Why It Hurts
RRULE is calendar-based Repeats by date, not by instant
Time zones shift Offsets change with DST
DST transitions Times can skip or repeat
Travel User's local zone changes
Rule changes Governments alter DST rules
Infinite recurrence Cannot expand forever
Exceptions Each occurrence can be modified

What Is a Recurring Event?

The Basic Concept

A recurring event is a single event definition that expands into many occurrences.

Component Meaning
DTSTART First occurrence
RRULE Recurrence rule
EXDATE Excluded dates
RDATE Additional dates
RECURRENCE-ID Modified instance

The RRULE Format

The iCalendar standard (RFC 5545) defines recurrence with the RRULE property.

Part Meaning
FREQ DAILY, WEEKLY, MONTHLY, YEARLY
INTERVAL Every N periods
COUNT Total occurrences
UNTIL End date
BYDAY Day of week
BYMONTHDAY Day of month
BYSETPOS Position in set

Example RRULE

FREQ=WEEKLY;BYDAY=MO;COUNT=10

This means: every Monday, 10 times.


The Core Conflict: Calendar Time vs Clock Time

Two Ways to Think About Repetition

Concept Meaning Example
Calendar time Same date and clock time Every Monday at 09:00 local
Absolute time Same instant Every 168 hours

Most meetings are defined in calendar time. People want to meet "every Monday at 09:00," not "every 168 hours."

Why This Creates Problems

When calendar time meets a time zone with DST, the UTC instant shifts.

Occurrence Local Time UTC Time
Winter Monday 09:00 EST 14:00 UTC
Summer Monday 09:00 EDT 13:00 UTC

The local time stayed the same. The UTC time changed.

The Conflict

Question Answer
Does the meeting stay at 09:00 local? Yes, if calendar-based
Does the meeting stay at 14:00 UTC? Yes, if absolute
Can it be both? No

Every calendar system must choose. Most choose calendar time, which is what users expect.


The DST Problem in Detail

Case 1: The Meeting That Skips

A weekly meeting at 02:30 local on a Sunday. Spring forward makes 02:30 not exist.

Week Local Time Exists?
Before DST 02:30 Yes
DST week 02:30 No
After DST 02:30 Yes

Result: The meeting is skipped, shifted, or handled per policy.

Case 2: The Meeting That Doubles

A weekly meeting at 01:30 local on a Sunday. Fall back makes 01:30 happen twice.

Week Local Time Occurrences
Before DST 01:30 1
DST week 01:30 2
After DST 01:30 1

Result: The meeting may appear twice or trigger duplicate reminders.

Case 3: The Traveling User

A user travels from New York to London. Their "09:00 meeting" now means something different.

Approach Behavior
Anchor to organizer's zone Time shifts for traveler
Anchor to attendee's zone Meeting moves for everyone
Floating time Same local time everywhere

Most calendars anchor to the organizer's zone, so the traveler sees a shifted time.


Floating Time vs Absolute Time

Floating Time

Floating time has no time zone. It means "the same wall-clock time everywhere."

Property Meaning
No zone Not tied to any location
Same local time 09:00 everywhere
Different instants 09:00 in each zone is different
Use case All-day events, birthdays

Absolute Time

Absolute time is tied to a specific instant, usually expressed in UTC.

Property Meaning
Has zone Tied to a location or UTC
Same instant One moment in time
Different local time Displays differently per zone
Use case Meetings, calls, deadlines

When to Use Each

Event Type Time Type
Weekly team meeting Absolute (organizer's zone)
All-day holiday Floating
Birthday Floating (date only)
Flight departure Absolute
Daily standup Absolute
Conference Absolute

The Common Mistake

Using floating time for meetings causes confusion when attendees are in different zones. Using absolute time for birthdays causes them to shift.


How Real Calendar Systems Handle It

Google Calendar

Aspect Behavior
Anchor Organizer's time zone
DST Meeting stays at local time
Travel Attendees see shifted time
All-day Floating

Microsoft Outlook

Aspect Behavior
Anchor Organizer's time zone
DST Configurable
Travel Attendees see shifted time
All-day Floating

Apple Calendar

Aspect Behavior
Anchor Event's time zone
DST Local time preserved
Travel Shifts per zone
All-day Floating

The Common Pattern

Pattern Purpose
Store zone with event Preserve intent
Expand in that zone Correct local times
Convert for display Per viewer
Keep exceptions Modified instances

The Exceptions Problem

Why Exceptions Matter

Not every occurrence is the same. One week the meeting moves. Another week it is canceled. Another week it is longer.

Exception Type Meaning
Canceled Use EXDATE
Moved Use RECURRENCE-ID
Modified Use RECURRENCE-ID
Added Use RDATE

How Exceptions Interact With Time Zones

A moved occurrence stores a new time — but in which zone?

Storage Behavior
Same zone as series Consistent
Different zone Ambiguous
Floating Same local time

The Exception Explosion

If every occurrence can be modified, the "single event" becomes a sparse set of instances. Systems must store the base rule plus all exceptions.

Scenario Storage
Pure series One rule
One exception Rule + one
Many exceptions Rule + many
All different Effectively separate events

The Infinite Recurrence Problem

Why You Cannot Expand Forever

A weekly meeting with no end date has infinite occurrences. You cannot generate them all.

Approach Behavior
Lazy expansion Generate as needed
Window expansion Generate for a range
Cached expansion Store computed instances

The Window Pattern

Most systems expand recurrence only for the visible window.

Window Occurrences Generated
One week view This week only
One month view This month only
One year view This year only

Why This Is Hard

Challenge Explanation
DST transitions Occurrences shift
Rule changes New tzdata versions
Exceptions Must be applied
Performance Must be fast
Consistency Same result everywhere

Rule Changes and Historical Data

The tzdata Problem

Time zone rules change. A recurrence computed in 2020 may produce different results in 2026.

Change Effect
DST rule change Occurrences shift
Offset change Local times shift
Zone rename ID may change
New zone New rules

What Happens to Old Events

Approach Behavior
Recompute with new rules Times may shift
Freeze with old rules Times stay, may be wrong
Store expanded instances Stable but verbose

The Practical Compromise

Store Purpose
Rule + zone Intent
Expanded instances Display
Version Which tzdata

This preserves intent while allowing display to be stable.


Best Practices for Developers

Storage

Practice Why
Store DTSTART with zone Preserve intent
Store RRULE as-is Standard format
Store exceptions explicitly Do not lose them
Store zone ID, not offset Handles DST
Record tzdata version Reproducibility

Expansion

Practice Why
Expand in the event's zone Correct local times
Convert to UTC for storage Comparison
Convert to viewer's zone for display User-friendly
Cache expanded instances Performance
Handle DST edges Skip or shift per policy

DST Policy

Case Recommended Policy
Missing time Shift forward one hour
Repeated time Use first occurrence
Ambiguous Document the choice
All-day events Floating, no shift

API Design

Principle Practice
Accept RRULE Standard format
Accept zone ID IANA format
Return expanded With offsets
Document DST behavior Be explicit
Version your API For rule changes

Quick Reference Card

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
   RECURRING EVENTS & TIME ZONES — CHEAT SHEET
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

WHY IT IS HARD:
  RRULE repeats in calendar time
  Time zones shift in clock time
  DST makes times skip or repeat

RRULE BASICS:
  FREQ=WEEKLY;BYDAY=MO;COUNT=10
  FREQ=DAILY;INTERVAL=2
  FREQ=MONTHLY;BYMONTHDAY=15
  FREQ=YEARLY;UNTIL=20301231T000000Z

CALENDAR TIME vs ABSOLUTE TIME:
  Calendar → same local time (meetings)
  Absolute → same instant (flights)
  Floating → same wall time everywhere (birthdays)

DST CASES:
  Missing time → shift forward
  Repeated time → first occurrence
  Document the policy

TRAVEL BEHAVIOR:
  Anchor to organizer's zone
  Traveler sees shifted time
  Most calendars work this way

EXCEPTIONS:
  EXDATE        → canceled occurrence
  RDATE         → added occurrence
  RECURRENCE-ID → modified occurrence

INFINITE RECURRENCE:
  Expand only the visible window
  Cache expanded instances

RULE CHANGES:
  Store rule + zone + tzdata version
  Recompute or freeze per policy

BEST PRACTICES:
  Store zone ID, not offset
  Expand in event's zone
  Convert for display only
  Handle DST edges explicitly

GOLDEN RULE:
  Store intent (rule + zone). Expand for display.

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
         Check live conversions at: /timezone-converter
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

Frequently Asked Questions

Why are recurring events with time zones so hard?

Recurrence rules repeat in calendar time, while time zones shift in clock time. When DST changes, the two conflict, creating skipped or duplicated occurrences.

What is RRULE?

RRULE is the iCalendar standard (RFC 5545) property that defines how an event repeats, using fields like FREQ, INTERVAL, COUNT, and BYDAY.

What happens to a recurring meeting during DST?

If the meeting is anchored to a local time, it stays at that local time. The UTC instant shifts by an hour. If the local time falls in a missing hour, the meeting may be skipped or shifted.

What is floating time?

Floating time has no time zone. It means the same wall-clock time everywhere. It is used for all-day events and birthdays.

What is absolute time?

Absolute time is tied to a specific instant, usually UTC. It displays differently in each time zone. It is used for meetings and flights.

Why do meetings shift when I travel?

Most calendars anchor meetings to the organizer's time zone. When you travel, your local time changes, so the meeting appears at a different local hour.

How do calendars handle exceptions?

They use EXDATE for canceled occurrences, RDATE for added ones, and RECURRENCE-ID for modified ones. The base rule plus exceptions defines the full series.

How do calendars handle infinite recurrence?

They expand recurrence only for the visible window, such as a week or month. They do not generate all occurrences at once.

What happens when time zone rules change?

Occurrences may shift. Systems either recompute with new rules or freeze with the old ones. Storing the tzdata version helps with reproducibility.

Should I store the offset or the zone ID?

Store the IANA zone ID, not the offset. The zone ID handles DST correctly; a fixed offset does not.

What is the best DST policy for recurring events?

Shift forward for missing times, use the first occurrence for repeated times, and document the choice. Consistency matters more than the specific rule.


Final Thoughts

Recurring events across time zones are hard because they combine two incompatible ways of thinking about time: calendar time and clock time. Add DST, travel, exceptions, and rule changes, and you have one of the most complex problems in software.

The industry solution is consistent: store the intent (rule plus zone), expand for display, handle DST edges explicitly, and version your data. Do this, and your calendar will behave correctly — even across DST, travel, and rule changes.

Three things to remember:

  1. Calendar time and clock time conflict. Recurrence chooses calendar time
  2. Anchor to a zone, not an offset. Offsets break with DST
  3. Handle DST edges explicitly. Missing and repeated times need a policy

Check time zone conversions instantly → /timezone-converter


Tags: recurring events time zones, RRULE explained, calendar software hardest problem, iCalendar recurrence, floating time vs absolute time, DST recurring meeting bug, weekly meeting across time zones, calendar recurrence rules, time zone converter, recurring event DST

Related Articles