← blog  /  scrapers

A timestamp without a zone is a guess

2026-10-20  ·  3 min read  ·  scrapers, tools

Scraped dates arrive as "2026-03-08 02:30" with nothing else. Some of those times never happened, some happened twice, and the gap between two cities moves during the year.

A scraper reads a time off a page: 2026-03-08 02:30. No zone, no offset. Whatever the schema says, what you have is a guess about when that was.

Times that never happened#

In the United States the clocks went forward on Sunday 2026-03-08, at 02:00 local time, straight to 03:00. So 02:30 that day in New York does not exist. A library has to pick something, and Python's zoneinfo picks the offset from before the jump.

Illustrative: a time that does not existpython
from datetime import datetime
from zoneinfo import ZoneInfo

ny, utc = ZoneInfo("America/New_York"), ZoneInfo("UTC")

t = datetime(2026, 3, 8, 2, 30, tzinfo=ny)
print(t.astimezone(utc))                 # 2026-03-08 07:30:00+00:00
print(t.astimezone(utc).astimezone(ny))  # 2026-03-08 03:30:00-04:00, not 02:30

It does not raise. Converting it to UTC and back gives you a different local time. A silent change is the dangerous kind.

Times that happened twice#

The clocks went back on Sunday 2026-11-01, so in New York 01:30 happens twice, an hour apart. Python lets you say which with fold.

Illustrative: a time that happened twicepython
first  = datetime(2026, 11, 1, 1, 30, tzinfo=ny, fold=0)
second = datetime(2026, 11, 1, 1, 30, tzinfo=ny, fold=1)
print(first.astimezone(utc))    # 2026-11-01 05:30:00+00:00
print(second.astimezone(utc))   # 2026-11-01 06:30:00+00:00

Same text on the page, one hour apart in UTC. Without a zone on the page, nothing tells you which one you were looking at.

The gap between two cities is not constant#

Europe and the United States change their clocks on different Sundays. In 2026 the US changed on 8 March and Europe on 29 March, and the autumn changes are on 25 October for Europe and 1 November for the US. In between, New York and Berlin are five hours apart instead of six: about three weeks in spring and one week in autumn.

"The US is six hours behind Germany" is true for most of the year and false for a month of it. A meeting scheduled on the rule gets one week a year wrong, every year.

What to store#

  1. UTC. An ISO 8601 string with an offset or a Z: 2026-03-08T07:30:00Z.
  2. The original string, exactly as printed. When the conversion is later found to be wrong, you can redo it.
  3. The zone, by its IANA name, like America/New_York. Not the abbreviation: CST means Central Standard Time in North America, China Standard Time and Cuba Standard Time.
  4. Not an offset on its own. +02:00 is Berlin in summer and Johannesburg all year. An offset says how far from UTC, not where, so it cannot tell you what the clock does next month.
  5. How you knew the zone. From the page's own markup, from the site's country, or assumed. Those three are not equally trustworthy, and the field should say which.

When the zone is only assumed, say so in the data. An assumed zone that looks like a known one will go wrong on exactly one Sunday a year and nobody will remember why.

On the command line, tzdiff shows the gap between zones for today and timecheck turns a unix timestamp into readable time. Both are small and one-purpose, in the style of the rest of the shelf.