Skip to content
AITroveRead. Build. Understand.
Make this comfortable

Python ZoneInfo: classify unique, repeated and missing local times

Last updated: 30 Sept 20264 min read
tutorial
IntermediateBy AITrove Editorial

A named-zone local clock reading can identify one UTC instant, two instants during a backward transition, or no instant during a forward transition.

Download Python source kit

Operation contract

The classifier accepts a naive datetime and an existing ZoneInfo object. It builds both fold candidates, converts each to UTC and back, and retains only candidates whose round-trip reproduces the same local fields. UTC instants are deduplicated because a normal time gives the same instant for both folds. The New York fixtures show one ordinary time, the repeated 01:30 autumn reading, and the missing 02:30 spring reading. No candidate is selected automatically.

Failure and ownership boundary

Attaching tzinfo does not itself reject a nonexistent local time. Returning two candidates lets the application ask for an offset or a deliberate earlier/later choice. Returning none requires rejection or a separately declared adjustment policy. Zone rules depend on the installed IANA data. Python zoneinfo and fold: two instants can share one clock label and Python datetime: require an offset before comparing timestamps provide the next step after classification.

Working program

python
from datetime import datetime, timezone
from zoneinfo import ZoneInfo

def local_candidates(local, zone):
    if type(local) is not datetime or local.tzinfo is not None or not isinstance(zone, ZoneInfo):
        raise ValueError("naive datetime and named zone required")
    candidates = set()
    for fold in (0, 1):
        instant = local.replace(tzinfo=zone, fold=fold).astimezone(timezone.utc)
        restored = instant.astimezone(zone).replace(tzinfo=None)
        if restored == local:
            candidates.add(instant)
    return sorted(candidates)

zone = ZoneInfo("America/New_York")
for local in (datetime(2024, 2, 1, 12), datetime(2024, 11, 3, 1, 30),
              datetime(2024, 3, 10, 2, 30)):
    print("candidates:", len(local_candidates(local, zone)))
print("repeated UTC:", [value.strftime("%H:%M") for value in
      local_candidates(datetime(2024, 11, 3, 1, 30), zone)])

Output

Output
candidates: 1
candidates: 2
candidates: 0
repeated UTC: ['05:30', '06:30']

Costs and limits

Two conversion paths give bounded application work per reading, plus zone transition lookup. This is classification for the installed data, not a promise about future government timezone changes. Persist the chosen instant and, when relevant, the original zone and selection policy.

Common Mistakes

  • Do not treat replace(tzinfo=zone) as validation of a local reading.
  • Do not silently resolve a repeated reading by whichever fold happens to be the default.

Connected lessons

Python zoneinfo and fold: two instants can share one clock label, Python datetime: require an offset before comparing timestamps, Java daylight-saving transitions: reject gaps and choose overlaps.

python
zone-local-classification
Storage details