Cedrik built Clockshift to inspect local schedules around clock changes. While checking a weekend example, I found a second surprise in Python: two timezone-aware values printed different UTC offsets and still compared equal.

Belgrade turns its clocks back on 25 October 2026, from 03:00 to 02:00. The local time 02:30 occurs twice. The published clock-change date supplies the calendar context; the code below checks the two occurrences.

Two values, one surprising comparison

from datetime import datetime, timezone from zoneinfo import ZoneInfo zone = ZoneInfo("Europe/Belgrade") first = datetime(2026, 10, 25, 2, 30, tzinfo=zone, fold=0) second = first.replace(fold=1) print(first.isoformat()) print(second.isoformat()) print(first == second) print((second - first).total_seconds()) print(len({first, second})) 
2026-10-25T02:30:00+02:00 2026-10-25T02:30:00+01:00 True 0.0 1 

Two occurrences went into a set. One came back out. A fairly quiet way to lose an hour.

The shared zone object matters. For aware datetimes with the same tzinfo object, Python compares the local date/time fields while ignoring tzinfo and fold. Same-zone subtraction also ignores the timezone. These are documented semantics, not a failed timezone lookup. The datetime reference explains both operations.

fold=0 selects the earlier occurrence of an ambiguous local time; fold=1 selects the later one. PEP 495 defines that distinction. Setting the flag is not a general validity check for arbitrary local timestamps.

Compare instants in UTC

first_utc = first.astimezone(timezone.utc) second_utc = second.astimezone(timezone.utc) print(first_utc.isoformat()) print(second_utc.isoformat()) print(first_utc == second_utc) print((second_utc - first_utc).total_seconds()) 
2026-10-25T00:30:00+00:00 2026-10-25T01:30:00+00:00 False 3600.0 

Once the question is elapsed time or identity of an instant, the UTC values preserve the distinction. A key based on those UTC values can distinguish these two occurrences too.

A recurring rule such as “02:30 every day in Belgrade” still needs its local time and timezone. Decide what should happen in the repeated hour, then compare or store the chosen instants. A fixed UTC hour would express a different schedule.

I ran the complete example on CPython 3.11.12 with available IANA timezone data. zoneinfo obtains that data from the system or the first-party tzdata package; its documentation covers the dependency.

Our prefilled browser check also shows both UTC candidates and exports the surrounding three dates. I checked that public output and downloaded its CSV.

This example does not establish that a cron job will execute twice. Your scheduler’s overlap policy still needs checking. The local clock has offered two appointments; the scheduler has to decide which ones it keeps.