Skip to content

fix(ui): bucket calendar issues by their real day in non-UTC timezones - #262

Merged
martian56 merged 1 commit into
mainfrom
fix/calendar-timezone-off-by-one
Jul 5, 2026
Merged

fix(ui): bucket calendar issues by their real day in non-UTC timezones#262
martian56 merged 1 commit into
mainfrom
fix/calendar-timezone-off-by-one

Conversation

@martian56

@martian56 martian56 commented Jul 5, 2026

Copy link
Copy Markdown
Member

Summary

Closes #140.

In the work-item Calendar layout, issues were bucketed into the wrong day cell for anyone outside UTC. Two date round-trips were to blame:

  • Each cell's lookup key was built as isoDate(date.toISOString().slice(0, 10)). The cell date is a local-midnight Date, so for a positive-offset client toISOString() rolls back to the previous UTC day and the cell key ends up one day early. Every issue then rendered in the next cell (a due-Jun-20 issue landed in the Jun-21 cell), and the per-day counts and "+N more" were off too.
  • isoDate parsed the target_date ("YYYY-MM-DDT00:00:00Z") into a Date and read its local components, which shifts negative-offset clients the other way.

Fix:

  • Cell keys now come from the date's local components (localKey), i.e. the calendar day the cell actually represents.
  • isoDate now takes the leading YYYY-MM-DD of target_date directly (the calendar day the backend stored), with no Date round-trip.

Buckets and cells agree on the calendar day in every timezone now.

Testing

  • npm run typecheck and npm run lint pass.
  • Browser-verified in Asia/Baku (UTC+4) — the reported repro timezone. In June 2026, "DUE-20th" (target_date 2026-06-20) now renders in the day-20 cell and "Child of Alpha" (2026-06-26) in the day-26 cell. Before the fix both were shifted +1 (day-21 / day-27).

AI assistance

This change was produced with the help of Claude Code (Claude Opus 4.8). See the Co-Authored-By trailer on the commit.

Summary by CodeRabbit

  • Bug Fixes
    • Fixed calendar day cells to use the correct local date key, reducing mismatches in day-specific issue views.
    • Improved date handling for calendar entries so UTC-based timestamps display consistently across time zones.

The Calendar layout keyed each day cell by round-tripping a local-midnight
date through toISOString(), which rolls back to the previous UTC day for
positive-offset clients, so every issue landed one cell late. Cell keys now
come from the date's local components, and isoDate takes the leading date
portion of the target_date directly instead of parsing it into a Date and
reading local fields (which shifted negative-offset clients the other way).
Buckets and cells now agree on the calendar day in every timezone.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@martian56
martian56 requested a review from a team as a code owner July 5, 2026 10:38
@martian56 martian56 added this to the Finish w Enhancements milestone Jul 5, 2026
@martian56 martian56 added bug Something isn't working UI labels Jul 5, 2026
@martian56 martian56 self-assigned this Jul 5, 2026
@martian56 martian56 added bug Something isn't working UI labels Jul 5, 2026
@strix-security

strix-security Bot commented Jul 5, 2026

Copy link
Copy Markdown

Strix Security Review

No security issues found.

Updated for 9ab76db.


Reviewed by Strix
Re-run review · Configure security review settings

@coderabbitai

coderabbitai Bot commented Jul 5, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 29334e5f-42a6-416f-8d69-e48a4bb51c63

📥 Commits

Reviewing files that changed from the base of the PR and between c370080 and 9ab76db.

📒 Files selected for processing (1)
  • apps/web/src/components/work-item/layouts/IssueLayoutCalendar.tsx

📝 Walkthrough

Walkthrough

The calendar layout's per-day cell key generation was changed from an ISO-string round-trip to a local date-key helper, and the isoDate function was rewritten to extract YYYY-MM-DD via regex instead of Date.parse, addressing a timezone-related off-by-one day bug.

Changes

Calendar day-key fix

Layer / File(s) Summary
Local date-key helper and cell keying
apps/web/src/components/work-item/layouts/IssueLayoutCalendar.tsx
Day-cell keys now use a new localKey(date) helper instead of isoDate(date.toISOString()...); isoDate is reworked to extract YYYY-MM-DD via regex with documentation on UTC-midnight timestamp assumptions.

Estimated code review effort: 2 (Simple) | ~10 minutes

Poem

A hop, a skip, one day undone,
No more shifting in the sun,
Local keys now light the way,
Each issue lands on its rightful day,
🐇📅 Calendar cells, aligned and true!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title is specific, concise, and matches the timezone day-bucketing fix.
Description check ✅ Passed The description covers the bug, fix, linked issue, testing, and AI disclosure, though it omits several optional template sections.
Linked Issues check ✅ Passed The change matches #140 by using local day keys and avoiding date round-trips that shifted issues by one day in non-UTC timezones.
Out of Scope Changes check ✅ Passed The diff stays confined to the Calendar layout date-keying fix and related helper logic, with no unrelated changes.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/calendar-timezone-off-by-one

Comment @coderabbitai help to get the list of available commands.

@martian56
martian56 merged commit 726a52c into main Jul 5, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] Calendar layout places issues in the wrong day cell in non-UTC timezones (off-by-one)

2 participants