Skip to content

Show a timed event on its local day, not its UTC day - #563

Open
armada877 wants to merge 5 commits into
basecamp:mainfrom
armada877:local-day-fix
Open

armada877 wants to merge 5 commits into
basecamp:mainfrom
armada877:local-day-fix

Conversation

@armada877

@armada877 armada877 commented Oct 12, 2026 •

Copy link
Copy Markdown

Problem

HEY reads a date in a JSON request as a UTC day. The TUI calendar and the event commands send only a date, so in New York the day 2026-09-14 runs from 8 PM on the 13th to 8 PM on the 14th.

An event that starts after 8 PM in New York therefore:

  • shows in the TUI day view on the next day, at its local hour (a 9:30 PM dinner on Sunday is drawn at 9:30 PM on Monday)
  • is missing from the TUI week view, which groups it on a local day outside the UTC week it was read in
  • is missing from hey event day, hey event week and hey event list for its own date
  • is not found by hey event edit <id> <date> for the date it shows on

Fix

  • Day and week reads also read the day before and the day after, and keep the timed events that overlap the local days (internal/calendarday). All-day events and the other recording types still come only from the main read.
  • Zone: the TUI uses the machine's zone, as it does for every time it draws. The CLI uses the HEY account's zone, as it already does for today, and falls back to the machine's zone with one notice when the account has none.
  • TUI day view clips an event that crosses midnight to the hours of the day. Before, an event that started the day before was drawn from its start hour.
  • hey event list: --starts-on and --ends-on are local days, and --ends-on is included, as docs/cli.md already describes.
  • hey event edit <id> <date> searches from the day before to the day after the date.

No command or flag is added, so .surface does not change.

Notes for review

Checks

  • make check passes.
  • New tests in internal/calendarday, internal/cmd/events_local_day_test.go and internal/tui/calendar_local_day_test.go fail without the fix. They cover New York, Tokyo, UTC and the 2026-11-01 DST change.
  • Checked by hand against a real account with read-only commands and the TUI: an evening event is on its own day in the day view, the week view and hey event day/week/list.

🤖 Generated with Claude Code


Summary by cubic

Shows timed events on their local day instead of their UTC day across the TUI calendar and the event commands, so an evening event no longer appears on the next day and hey event edit finds it by the date it shows on.

  • Day and week reads also read the day before and after, keeping only the timed events that overlap the local days; each day or week read now makes two extra requests.
  • hey event list treats --starts-on and --ends-on as local days and includes --ends-on, so its default window is today plus the 29 days after; a repeating series is kept only if it starts before the last day.
  • hey event edit <id> <date> searches the day before and after the date.
  • The TUI uses the machine's time zone; the CLI uses the HEY account's zone, falling back to the machine's with one notice.
  • The TUI day view clips events that cross midnight to that day's hours, so a multi-day event starts at the first hour of each day it spans.
  • A timed event that ends exactly at local midnight of a day is not on that day.

Written for commit c5b3fee. Summary will update on new commits.

View guided diff

HEY reads a date in a JSON request as a UTC day. In New York, the day
2026-09-14 then runs from 8 PM on the 13th to 8 PM on the 14th. The TUI
calendar and the event commands send only a date, so an event after 8 PM
showed on the next day, and the TUI drew it there at its local hour. The
week view dropped it, because it grouped the event on a day outside the
UTC week.

The day and week reads now also read the day before and the day after,
and keep the timed events that overlap the local days. All-day events and
the other recording types still come from the main read. The TUI uses the
machine's zone, as it does for every time it draws. The CLI uses the HEY
account's zone, as it does for today, and the machine's zone when the
account has none.

- hey tui: the day and week views show an evening event on its own day.
  The day view clips an event that crosses midnight to the hours of the
  day.
- hey event day and hey event week: the same local days.
- hey event list: --starts-on and --ends-on are local days, and --ends-on
  is included, as docs/cli.md already said.
- hey event edit <id> <date>: finds an evening or early-morning event by
  the date it shows on.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Copilot AI balanced review requested due to automatic review settings October 12, 2026 15:07
@armada877
armada877 requested a review from a team as a code owner October 12, 2026 15:07

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

Recurring events can leak from buffer days, the default list becomes 31 days, and a new test fixture has a data race.

4 open findings
What changed in this PR

Corrects calendar grouping so timed events appear on their local day across the CLI and TUI.

Changes:

  • Reads adjacent UTC days and filters events by local-day overlap.
  • Makes CLI date ranges account-zone aware and inclusive.
  • Clips multi-day events within TUI day boundaries.

[!TIP]
If you aren't ready for review, convert to a draft PR.
Click "Convert to draft" or run gh pr ready --undo.
Click "Ready for review" or run gh pr ready to reengage.

File Description
internal/​calendarday/​calendarday.go Adds local-day span and event filtering.
internal/​calendarday/​calendarday_test.go Tests overlap, zones, DST, and deduplication.
internal/​cmd/​account_zone.go Adds reusable read-zone fallback handling.
internal/​cmd/​account_zone_test.go Updates account-zone expectations.
internal/​cmd/​calendar_commands_test.go Updates widened event-list request tests.
internal/​cmd/​events.go Applies local-day filtering to list and edit.
internal/​cmd/​events_test.go Tests widened edit searches.
internal/​cmd/​events_period.go Merges adjacent day events into period reads.
internal/​cmd/​events_period_test.go Updates day and week fixtures.
internal/​cmd/​events_local_day_test.go Adds CLI local-day behavior coverage.
internal/​tui/​calendar.go Loads adjacent days for TUI views.
internal/​tui/​calendar_views.go Clips events to the displayed day.
internal/​tui/​calendar_test.go Updates week request expectations.
internal/​tui/​calendar_local_day_test.go Adds TUI zone and clipping coverage.
internal/​tui/​habit_form_test.go Accommodates adjacent calendar reads.
docs/​cli.md Documents CLI local-day semantics.
docs/​tui.md Documents TUI local-zone behavior.

🧠 Review effort: Balanced


💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread internal/calendarday/calendarday.go Outdated
Comment thread internal/cmd/events.go
Comment thread internal/cmd/events_local_day_test.go Outdated
Comment thread docs/cli.md Outdated

@cubic-dev-ai cubic-dev-ai Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

All reported issues were addressed across 17 files

Reply to a comment to ask cubic a question or push back. It learns from your replies.

View guided diff | Re-trigger cubic

Comment thread internal/calendarday/calendarday_test.go Outdated
Comment thread internal/cmd/events.go
Comment thread docs/cli.md Outdated
Comment thread internal/cmd/events_local_day_test.go Outdated
Comment thread docs/tui.md Outdated
Comment thread internal/cmd/events_period.go
armada877 and others added 2 commits October 12, 2026 11:20
- hey event list keeps a series row only if the series starts before the
  end of the last day. The list reads a day either side, and a series
  that starts in that extra day is not in the window.
- The default event list window is today and the 29 days after it. With
  --ends-on included, that is 30 days, as the help says.
- The local-day test server records requests under a mutex, because the
  two neighbour reads run at the same time.
- The docs and help no longer say that hey event edit uses the account's
  zone. It looks from the day before the date to the day after it.
- docs/tui.md says that a timed event moves to its local day and an
  all-day event stays on its dates.
- The day-before test case reads its event from the day before only.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The edge cases of the local-day rules are now table tests in
internal/calendarday only. The CLI and TUI tests check only that each
command and view uses those rules, with one test each. The three new
test files go from 888 to 395 lines.

The TUI takes the zone of its local days from the day on screen, which
is time.Local in the app. The tests can then use a zone of their own
without changing time.Local, which raced with other tests under -race.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@cubic-dev-ai cubic-dev-ai Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

All reported issues were addressed across 5 files (changes from recent commits).

Reply with feedback, questions, or to request a fix.

View guided diff | Re-trigger cubic

Comment thread internal/tui/calendar_local_day_test.go
Comment thread internal/calendarday/calendarday_test.go
- calendarday: an event that ends exactly at local midnight of the day
  is not on that day.
- tui: the rendered day view starts a multi-day stay at the first hour
  of its middle day, so the view uses the clipped columns.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟢 Approved

The local-day filtering, boundary handling, documentation, and timezone-focused tests are consistent and complete.

0 open findings

4 resolved since last review

🧠 Review effort: Balanced

Give calendarday a package comment, and give each new function and type
a doc comment in the voice of the code around it. Put the public
functions before the private ones and the methods last, each below its
callers. Move dayColumns below renderDayView, its only caller. No
behaviour changes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

This branch has not been deployed

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants