Skip to content

fix(room): display backend timestamps in the viewer's local zone#345

Merged
91jaeminjo merged 1 commit into
mainfrom
fix/timestamp-display
Jun 11, 2026
Merged

fix(room): display backend timestamps in the viewer's local zone#345
91jaeminjo merged 1 commit into
mainfrom
fix/timestamp-display

Conversation

@91jaeminjo

Copy link
Copy Markdown
Collaborator

What

Backend timestamps arrive as UTC instants (parseTimestamp appends Z and calls .toUtc()). Two room display sites read calendar fields off those instants without .toLocal() first, so they rendered the wrong time-of-day (or a date off by one) for any viewer outside UTC:

  • documents_card.dart _formatDateTime — full date and time, wrong hour on every render.
  • thread_tile.dart _formatRelativeTime — the >7-day numeric-date fallback only.

Both bugs originated from copy-pasting a relative-time formatter that read raw fields, so the fix also removes that duplication.

Changes

  • Fix: .toLocal() at both display sites.
  • Consolidate: extract the duplicated relative-time label into a shared, already-localized formatRelativeTime in lib/src/shared/relative_time.dart, with .toLocal() normalized at the top of the function so the fallback can't regress. thread_tile, room_card, and room_grid_card all call it; the duplicate _formatRelativeTime and lobby's formatRelativeActivity are deleted.
  • Kept in place: lobby's bucketFor / ActivityBucket (single consumer, lobby-specific section headers); documents_card's absolute formatter (different concept, single caller — not shared).

Design notes

shared/ (not core/) is the home: core/ is shell infrastructure, and a pure presentation helper shared by two sibling modules must live below both — room → lobby would be a wrong directional dependency. shared/ already holds the pure-function file_type_icons.dart.

Tests

  • New test/shared/relative_time_test.dart — thresholds + a UTC-instant fallback regression case.
  • New regression in documents_card_test.dart — the existing timestamp test used a local DateTime, so it never exercised the UTC→local path (confirmed RED before the fix, GREEN after).
  • Caveat: both UTC regression tests can only fail on a non-UTC runner; the top-of-function normalization is the durable guard.

Full suite green, dart format clean, flutter analyze zero warnings.

Closes #338

🤖 Generated with Claude Code

Backend timestamps are UTC instants. Two room display sites read calendar
fields without converting to local first: the document card's date+time
formatter and the thread tile's >7-day date fallback. Both showed the
wrong time-of-day (or a date off by one) for viewers outside UTC.

Add .toLocal() at both sites. Consolidate the duplicated relative-time
formatter into a shared, already-localized formatRelativeTime in
lib/src/shared/, normalizing to local at the top so the fallback cannot
regress; lobby and room both call it. Keep the lobby-specific activity
buckets where they are.

Closes #338

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@91jaeminjo 91jaeminjo merged commit 89ebc41 into main Jun 11, 2026
6 checks passed
@91jaeminjo 91jaeminjo deleted the fix/timestamp-display branch June 11, 2026 15:42
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.

Room module: UTC timestamps displayed without .toLocal() (wrong time-of-day / date)

1 participant