What Actually Happens at 2:00 AM on the First Sunday in November?

Published on May 26, 2026 by The Kestrel Tools Team ‱ 7 min read

You’ve written a scheduling function. It stores timestamps, converts between timezones, handles user input. Everything works — until someone files a bug report on the first Sunday in November. The unix timestamp timezone conversion DST problem just bit you, and the fix isn’t what you’d expect.

The issue is deceptively simple: at 2:00 AM Eastern on November 1, 2026, clocks “fall back” to 1:00 AM. That means 1:30 AM happens twice. If your code stores "2026-11-01 01:30:00 America/New_York" — which 1:30 AM did you mean?

Why Unix Timestamp Timezone Conversion DST Breaks Your Code

Let’s make this concrete. Consider these two moments in time:

  • 1:30 AM EDT (UTC-4) = Unix timestamp 1793682600
  • 1:30 AM EST (UTC-5) = Unix timestamp 1793686200

Those are 3,600 seconds apart — a full hour — but both display as “1:30 AM” in the America/New_York timezone. This is the fold problem: a single local time maps to two different instants in UTC.

Most datetime libraries default to one or the other without telling you. Python’s datetime before 3.6 silently picked the first occurrence. JavaScript’s Date constructor picks
 well, it depends on the engine.

The Three Ways Time Gets Ambiguous

DST transitions create two distinct failure modes, plus one that surprises everyone:

1. The Fold (Fall Back)

When clocks move backward, a range of local times occurs twice:

UTC TimestampUnix EpochLocal Time (ET)Offset
2026-11-01 05:30 UTC179368260001:30 AM EDTUTC-4
2026-11-01 06:30 UTC179368620001:30 AM ESTUTC-5

Any local time between 1:00 AM and 1:59 AM on fall-back day is ambiguous.

2. The Gap (Spring Forward)

When clocks jump forward, a range of local times never exists:

On March 8, 2026 at 2:00 AM, clocks jump to 3:00 AM. The time “2:30 AM” simply doesn’t happen. If your code tries to construct this datetime, it’s working with a moment that never occurred.

3. The Political Surprise

Timezone rules change. Morocco abolished DST in 2018. Egypt has switched it on and off multiple times. Russia moved to permanent winter time in 2014. Your hardcoded UTC offset assumptions have a shelf life.

Unix Timestamps: The Escape Hatch

A Unix timestamp is simply the count of seconds since January 1, 1970 00:00:00 UTC. It has no timezone. It has no DST. It’s just a number on a monotonic timeline.

This is why the standard advice is: store timestamps in UTC (or as Unix epoch seconds), convert to local time only at display time.

// Bad: storing local time strings
const meeting = "2026-11-01 01:30:00 America/New_York"; // Which one?

// Good: storing Unix timestamp
const meeting = 1793682600; // Unambiguous: one specific instant

// Convert to local only when displaying
const display = new Intl.DateTimeFormat('en-US', {
  timeZone: 'America/New_York',
  dateStyle: 'full',
  timeStyle: 'long'
}).format(new Date(meeting * 1000));

The Unix timestamp 1793682600 always means the same moment. No ambiguity. No fold. No gap.

The Conversion Gotchas Nobody Warns You About

Storing in UTC solves the ambiguity problem, but conversion still has sharp edges:

Gotcha 1: “Just subtract the offset” is wrong

Timezone offsets aren’t fixed. America/New_York is UTC-5 in winter and UTC-4 in summer. You need the IANA timezone database (the tz database), not a hardcoded offset.

Gotcha 2: Recurring events are harder than they look

“Every day at 2:30 PM” stored as a Unix timestamp interval (86400 seconds) will drift by an hour across DST boundaries. Recurring events need to be stored as local time rules (“14:30 in America/New_York”) and resolved to UTC at evaluation time.

Gotcha 3: Leap seconds exist (but probably don’t affect you)

Unix timestamps officially don’t count leap seconds — a “Unix day” is always exactly 86400 seconds. The system clock gets adjusted (via NTP smearing or stepping), but your time() call returns a smooth count. Unless you’re doing sub-second GPS timing or astronomical calculations, you can safely ignore this.

Gotcha 4: Database timezone settings

PostgreSQL’s timestamp type has no timezone; timestamptz stores UTC and converts on read. MySQL’s TIMESTAMP converts to UTC on store and back on read (using the session timezone). DATETIME stores the literal value with no conversion. Know which one you’re using.

A Practical Decision Framework

Here’s how to think about time storage in your application:

Store as Unix timestamp / UTC when:

  • Recording when something happened (logs, events, created_at)
  • Scheduling a specific instant (“this meeting starts at this exact moment”)
  • Comparing or sorting events chronologically
  • Communicating between systems (APIs, message queues)

Store as local time + timezone when:

  • Recurring events (“every Tuesday at 9 AM in the user’s timezone”)
  • Date-only values (birthdays, holidays)
  • User-facing scheduling that should “follow the clock”

How Different Languages Handle the Fold

Modern datetime libraries have gotten better at surfacing the ambiguity:

Python 3.6+ — datetime objects have a fold attribute (0 = first occurrence, 1 = second):

from datetime import datetime
from zoneinfo import ZoneInfo

dt = datetime(2026, 11, 1, 1, 30, tzinfo=ZoneInfo("America/New_York"))
# fold=0 → EDT (first 1:30 AM)
# fold=1 → EST (second 1:30 AM)

JavaScript (Temporal API) — the upcoming Temporal.ZonedDateTime has explicit disambiguation:

Temporal.ZonedDateTime.from({
  year: 2026, month: 11, day: 1,
  hour: 1, minute: 30,
  timeZone: 'America/New_York'
}, { disambiguation: 'earlier' }); // or 'later', 'compatible', 'reject'

Java (java.time) — ZonedDateTime.ofLocal() accepts a preferred offset to resolve ambiguity.

The November 2026 Transition

For reference, here’s what happens on November 1, 2026 in the US Eastern timezone:

  • 05:59:59 UTC → 01:59:59 AM EDT (UTC-4)
  • 06:00:00 UTC → 01:00:00 AM EST (UTC-5) ← clocks fall back
  • 06:59:59 UTC → 01:59:59 AM EST (UTC-5)
  • 07:00:00 UTC → 02:00:00 AM EST (UTC-5) ← ambiguity window ends

The fold window is 05:00 UTC to 06:00 UTC (the hour from 1:00-1:59 AM local occurs twice).

Try It Yourself

If you’re working with Unix timestamps and need to verify conversions across DST boundaries, a Unix Timestamp Converter that’s timezone-aware can save you from the guessing game. Paste in an epoch value, pick a timezone, and see exactly which local time it resolves to — fold and all.

Key Takeaways

  • Unix timestamps are unambiguous by design — they count seconds from a fixed point in UTC
  • The “fall back” DST transition creates a fold where one local time maps to two UTC instants
  • Store instants as UTC/epoch; store recurring schedules as local time + IANA timezone name
  • Never hardcode UTC offsets — use the tz database
  • Modern language APIs (Python fold, JS Temporal disambiguation) now surface the ambiguity explicitly

The next time you write new Date(), remember: that timestamp you just created is already in UTC under the hood. The complexity only appears when you try to display it in a local timezone. Keep that boundary clean, and the first Sunday in November stays boring.