· 4 min read · Billy Lui

How Temporal Cortex Handles DST Transitions (So Your Agent Doesn't Have To)

Daylight Saving Time transitions are the most common source of calendar bugs. They happen twice a year, they affect every timezone-aware application, and they break in ways that are subtle enough to ship unnoticed.

For AI agents managing calendars, DST creates three distinct failure modes.

Failure mode 1: The shifted meeting

A weekly standup is scheduled for 9:00 AM Eastern every Monday. On March 8, 2026 (US spring-forward), clocks jump from 2:00 AM to 3:00 AM. The UTC offset for Eastern Time changes from -05:00 (EST) to -04:00 (EDT).

The naive approach: Add 7 days to the previous occurrence’s UTC timestamp. Last Monday was 2026-03-02T14:00:00Z (9am EST). Add 7 days: 2026-03-09T14:00:00Z. But in EDT, that’s 10:00 AM, not 9:00 AM. The meeting shifted by an hour.

The correct approach: Preserve the wall-clock time (9:00 AM) and recompute the UTC offset. March 9 in EDT is -04:00, so the correct UTC time is 2026-03-09T13:00:00Z.

This is exactly what expand_rrule does. Given a timezone-aware RRULE, the Truth Engine preserves the local time across DST boundaries:

// expand_rrule input
{
  "rrule": "FREQ=WEEKLY;BYDAY=MO",
  "dtstart": "2026-03-02T09:00:00",
  "timezone": "America/New_York",
  "count": 4
}

// Output
{
  "instances": [
    { "start": "2026-03-02T14:00:00Z" },
    { "start": "2026-03-09T13:00:00Z" },
    { "start": "2026-03-16T13:00:00Z" },
    { "start": "2026-03-23T13:00:00Z" }
  ]
}

Notice the UTC hour changes from 14:00 to 13:00 at the DST boundary — but the local time stays 9:00 AM.

Failure mode 2: The gap hour

During spring-forward, 2:00 AM to 2:59 AM doesn’t exist. Clocks jump directly from 1:59 AM to 3:00 AM. If a recurring event is scheduled at 2:30 AM (rare but real — think overnight batch jobs, on-call rotations, or timezone-converted events), that occurrence falls into the gap.

LLMs handling this edge case typically generate the timestamp anyway — 2026-03-08T02:30:00-05:00 — which represents a time that literally doesn’t exist on that date. Some calendar APIs silently adjust it to 3:30 AM. Others reject it. The behavior is inconsistent.

The Truth Engine follows RFC 5545’s algorithm: when an occurrence falls in a DST gap, it’s adjusted to the first valid time after the transition (in this case, 3:00 AM EDT).

Failure mode 3: The ambiguous hour

During fall-back (November 1, 2026 in the US), clocks go from 2:00 AM back to 1:00 AM. The hour from 1:00 AM to 1:59 AM occurs twice — once in EDT (-04:00) and once in EST (-05:00).

A recurring event at 1:30 AM hits this ambiguity. Which 1:30 AM? The first one (still daylight time) or the second one (now standard time)?

The Truth Engine resolves this deterministically: it uses the offset that was in effect before the transition (the first occurrence of the ambiguous hour). This matches RFC 5545’s behavior and ensures every expansion produces the same result across platforms.

How adjust_timestamp handles DST

The adjust_timestamp tool applies duration adjustments with DST awareness. The key principle: +1d means “same wall-clock time tomorrow,” not “+24 hours.”

// adjust_timestamp input
{
  "datetime": "2026-03-07T23:00:00-05:00",
  "adjustment": "+1d",
  "timezone": "America/New_York"
}

// Output (spring-forward happens March 8)
{
  "original": "2026-03-07T23:00:00-05:00",
  "adjusted_utc": "2026-03-09T03:00:00+00:00",
  "adjusted_local": "2026-03-08T23:00:00-04:00",
  "adjustment_applied": "+1d"
}

Adding one day to 11:00 PM on March 7 (EST) produces 11:00 PM on March 8 (EDT). The UTC representation differs by 23 hours (not 24) because the day was only 23 hours long due to spring-forward. But the wall-clock time is preserved.

Compare with the naive “+24 hours” approach, which would produce midnight on March 9 — wrong by one hour.

How get_temporal_context warns about upcoming transitions

The get_temporal_context tool reports the next DST transition and how many days away it is:

{
  "dst_active": false,
  "next_dst_transition": "2026-03-08T07:00:00+00:00",
  "next_dst_direction": "spring-forward",
  "days_until_dst_transition": 3
}

An agent reading this knows that any scheduling within the next 3 days crosses a DST boundary. Combined with the Agent Skill’s procedural guidance, the agent can proactively mention the timezone change to the user: “Note: this meeting crosses the spring-forward boundary. It will be at 9:00 AM EDT (UTC-4), not EST (UTC-5).”

Why this matters for AI agents

DST bugs are invisible at the time of booking. The event looks correct on the day it’s created. The error only manifests when the recurring instance crosses a DST boundary — potentially weeks or months later. By then, the user has forgotten the agent scheduled it, and the bug surfaces as a mysteriously shifted meeting. This is especially critical in cross-timezone workflows like recruiting, where candidates and interviewers span multiple regions — see Building an AI Recruiting Coordinator for a concrete example.

Deterministic tools eliminate this class of errors entirely. The Truth Engine handles DST transitions because it implements RFC 5545’s timezone-aware algorithm, not because it “understands” DST. It computes the correct answer the same way every time.

npx @temporal-cortex/cortex-mcp

All Layer 1 temporal tools (get_temporal_context, resolve_datetime, convert_timezone, compute_duration, adjust_timestamp) and expand_rrule are DST-aware, pure computation, and require no API keys or network access.