Skip to content

Bucket and show dates in Dublin time, not UTC #103

Description

@baz8080

uisce stores and computes in UTC, which is right. But it also cuts every month and day at UTC midnight and prints every date on UTC's calendar. From late March to late October that is an hour off Irish time, so anything published between 00:00 and 01:00 Irish time lands on the previous day, and at a month end in the previous month.

esb had the same bug and fixed it in baz8080/esb#51 (notes/grading.md § Months and days are Dublin's). lifts fixed it on 2026-08-18 (notes/site.md § Displayed instants are Dublin wall-clock, and so are the day buckets). rail-delays already buckets in Dublin time.

Where

  • src/uisce/site.py:404: parse_dt gives aware UTC. That's correct for storage and arithmetic.
  • site.py:408: month_bounds builds datetime(year, month, 1, tzinfo=timezone.utc). It feeds region_month (counts, person-hours, availability, grade), top_events, the per-county month loop, and eval_overlap.py / eval_recurrence.py.
  • site.py:415: month_list takes the months of a UTC now.
  • site.py:2228-2235: the day cells are UTC days. The comment at 2233 makes this a deliberate choice: "both sides read UTC dates, so they agree on the boundary". That is the decision to revisit.
  • site.py:2279: the median month tests first_pub against the UTC bounds.
  • site.py:2314: "current month" is now.strftime("%Y-%m"), in UTC.
  • Dates shown to readers, all taken from a UTC datetime:
    • since is case.start.strftime("%Y-%m-%d") (1148, 1159).
    • meta["start"] (2129).
    • History start (1421) and end (1432).
  • site.py:195-205: closed_on mixes zones. It returns a Dublin date for an observed completion but a UTC date for a paired lift or closed_at.
  • src/uisce/site.html:326: today is new Date().toISOString().slice(0, 10), the UTC date. It drives isPartial() and "still to come" in the day bars.
  • Tests pin UTC midnight: tests/test_site.py:2014, 2021 and 341.

A worked example

A notice published at 00:30 Irish time on 1 July 2026 is STARTDATE 2026-06-30T23:30Z.

  • The open list reads "since Tue 30 Jun", and the area history files it under June 2026.
  • The static page reads "Tue 30 Jun", and the Atom feed says "published 2026-06-30".
  • The 30 June cell is coloured, and the half hour is charged to June's person-hours and median.
  • An outage from 00:10 to 00:50 Irish time on 2 July colours only the 1 July cell.
  • From 00:00 to 01:00 Irish time on 1 August, the app still treats July as the month in progress.

Already right

  • Notice ends are parsed from Dublin wall-clock and converted to UTC (build.py:38-61).
  • Recurring windows are expanded in Dublin (site.py:696-704).

Proposed rule (what esb and lifts do)

  • Keep storing and computing in UTC.
  • Cut months and days at Dublin midnight, held as UTC instants, never as Dublin-zoned datetimes. Python subtracts two datetimes that share a zone by their wall clocks, which loses the hour at a clock change.
  • Take the day count from calendar.monthrange, never from subtracting the bounds. A Dublin March is 23 hours short and October 25 hours long.
  • Convert every printed date to Dublin, including today in the JS: Intl.DateTimeFormat with timeZone: "Europe/Dublin", which is what esb's site.html now does.
  • Note the new decision in notes/, and update the tests that pin UTC midnight.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions