Skip to content

Fix legislation action dates displaying one day early - #203

Merged
calebyhan merged 2 commits into
mainfrom
#200/legislation-action-date-offset
Aug 21, 2026
Merged

Fix legislation action dates displaying one day early#203
calebyhan merged 2 commits into
mainfrom
#200/legislation-action-date-offset

Conversation

@calebyhan

Copy link
Copy Markdown
Contributor

Summary

  • Action dates are stored as UTC midnight (new Date(dateString).toISOString() on a bare YYYY-MM-DD input from the date picker).
  • The actions timeline rendered them with toLocaleDateString() with no timezone, which uses the browser's local timezone — for any US timezone (behind UTC), UTC midnight rolls back to the previous local day.
  • Fixed by formatting with timeZone: "UTC", matching the pattern already used correctly on the public legislation search page.

Fixes #200

Test plan

  • tsc --noEmit passes
  • Frontend build passes
  • Manually add an action with a specific date on the admin legislation page and confirm the timeline shows the same date entered

Action dates are stored as UTC midnight (via new Date(dateString)
.toISOString() on a bare YYYY-MM-DD input), but the timeline rendered
them with toLocaleDateString() in the browser's local timezone, which
rolls UTC midnight back to the previous local day in any timezone
behind UTC. Force UTC when formatting for display, matching the
pattern already used correctly in the public legislation search page.

Fixes #200
@github-actions

github-actions Bot commented Aug 21, 2026

Copy link
Copy Markdown

Test Results

573 tests  ±0   573 ✅ ±0   50s ⏱️ -1s
  1 suites ±0     0 💤 ±0 
  1 files   ±0     0 ❌ ±0 

Results for commit 5b7e1e8. ± Comparison against base commit b510850.

♻️ This comment has been updated with latest results.

@calebyhan
calebyhan marked this pull request as ready for review August 21, 2026 01:11
@MasonMines2006

Copy link
Copy Markdown
Collaborator

Fix looks right for this page, but it may only cover half the bug. The public legislation detail page (frontend/src/app/legislation/[id]/page.tsx:40) renders the same action_date field a different way — format(parseISO(action.action_date), "MMMM d, yyyy") via date-fns, which also defaults to local time rather than UTC. If action_date is stored as UTC midnight, that's likely the same off-by-one-day bug, just unfixed on the page actual site visitors see. Worth checking/fixing there too before merging, or as a quick follow-up.

@calebyhan

Copy link
Copy Markdown
Contributor Author

Took a look — good catch to double-check, but tracing it through, this turns out not to be a second instance of the bug.

The admin-page bug (this PR) was in how the date got displayed, not how it's stored. action_date (and date_introduced, date_last_action) is a SQL Date column, and the Pydantic schema types it as date (backend/app/schemas/legislation.py:10). Even though the admin form submits a full ISO datetime like 2026-04-07T00:00:00.000Z, Pydantic extracts just the calendar date, and the API always serializes it back as a bare 2026-04-07 — never a timestamp, never a Z suffix. Confirmed directly:

>>> M(d='2026-04-07T00:00:00.000Z')
M(d=date(2026, 4, 7))
>>> M(d='2026-04-07T00:00:00.000Z').model_dump_json()
'{"d":"2026-04-07"}'

parseISO (date-fns) treats date-only strings as local time, not UTC — that's specifically why it exists, unlike the native new Date("2026-04-07") used in the admin bug, which parses as UTC. Verified empirically:

TZ=America/New_York
parseISO("2026-04-07")      -> Apr 7 00:00 local  -> format(...) -> "April 7, 2026"  (correct)
new Date("2026-04-07")      -> UTC midnight        -> toLocaleDateString() -> "4/6/2026"  (the actual bug, fixed here)

So legislation/[id]/page.tsx:38 (and the same parseISO+format pattern on date_introduced/date_last_action in that file, plus nominations/page.tsx and recent/page.tsx) are already correct as written — they just look similar to the buggy pattern at a glance. No follow-up needed there.

Also merged latest main into this branch (#202/#204 are in now) so it's up to date and mergeable; type check still passes clean.

@MasonMines2006 MasonMines2006 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@calebyhan
calebyhan merged commit acb8eb5 into main Aug 21, 2026
3 checks passed
@calebyhan
calebyhan deleted the #200/legislation-action-date-offset branch August 21, 2026 14:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Off-by-one error on legislative database dates

2 participants