fix(i18n): use Intl.DateTimeFormat for locale-aware date/time display#894
Conversation
…d timeline
Replaces hardcoded moment().format('MMM D'), moment().format('ddd, MMM D'),
and moment().format('HH:mm:ss') calls with locale-aware Intl.DateTimeFormat
helpers, so dates and times respect the browser's locale instead of always
rendering in English.
Adds three new helpers to src/util/time.ts:
- format_date_short(): "Jun 15" → "15 jun" in sv-SE
- format_date_with_weekday(): "Mon, Jun 15" → "mån 15 jun" in sv-SE
- format_time_of_day(): "14:30:05" or "2:30:05 PM" per locale
Fixes the date labels in Trends.vue (range labels, busiest-day label)
and the event clocktime in the timeline visualization popup.
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #894 +/- ##
==========================================
- Coverage 35.59% 35.58% -0.01%
==========================================
Files 36 36
Lines 2152 2161 +9
Branches 398 401 +3
==========================================
+ Hits 766 769 +3
- Misses 1365 1371 +6
Partials 21 21 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Greptile SummaryThis PR replaces hardcoded
Confidence Score: 5/5Safe to merge — the three new helpers are straightforward Intl.DateTimeFormat wrappers that match the timezone handling of the moment calls they replace. All three call sites pass valid Date objects or ISO strings, timezone handling is equivalent to the replaced moment.format() calls (both convert to local time), and the hour: '2-digit' fix already landed in the head commit ensures consistent zero-padding in the timeline popup. No files require special attention. Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[Event timestamp / moment.Moment / Date string] --> B{format helper}
B --> C[format_date_short\nIntl month+day]
B --> D[format_date_with_weekday\nIntl weekday+month+day]
B --> E[format_time_of_day\nIntl hour+minute+second]
C --> F[Trends.vue\ncurrentRangeLabel\npreviousRangeLabel]
D --> G[Trends.vue\nbusiestDay.label]
E --> H[timeline.ts\nclocktime popup td]
style C fill:#d4edda
style D fill:#d4edda
style E fill:#d4edda
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
A[Event timestamp / moment.Moment / Date string] --> B{format helper}
B --> C[format_date_short\nIntl month+day]
B --> D[format_date_with_weekday\nIntl weekday+month+day]
B --> E[format_time_of_day\nIntl hour+minute+second]
C --> F[Trends.vue\ncurrentRangeLabel\npreviousRangeLabel]
D --> G[Trends.vue\nbusiestDay.label]
E --> H[timeline.ts\nclocktime popup td]
style C fill:#d4edda
style D fill:#d4edda
style E fill:#d4edda
Reviews (4): Last reviewed commit: "fix(time): use 2-digit hour to ensure co..." | Re-trigger Greptile |
|
@greptileai review |
|
@greptileai review |
1 similar comment
|
@greptileai review |
|
All checks passing and ready for merge:
The new |
…ActivityWatch#894) * fix(i18n): use Intl.DateTimeFormat for date/time display in Trends and timeline Replaces hardcoded moment().format('MMM D'), moment().format('ddd, MMM D'), and moment().format('HH:mm:ss') calls with locale-aware Intl.DateTimeFormat helpers, so dates and times respect the browser's locale instead of always rendering in English. Adds three new helpers to src/util/time.ts: - format_date_short(): "Jun 15" → "15 jun" in sv-SE - format_date_with_weekday(): "Mon, Jun 15" → "mån 15 jun" in sv-SE - format_time_of_day(): "14:30:05" or "2:30:05 PM" per locale Fixes the date labels in Trends.vue (range labels, busiest-day label) and the event clocktime in the timeline visualization popup. * fix(lint): format options objects per prettier style * fix(time): use 2-digit hour to ensure consistent zero-padding in timeline --------- Co-authored-by: Bob <bob@gptme.org>
Summary
Fixes inconsistent date/time display that hardcoded English (moment format strings) instead of respecting the browser's locale. Reported in ActivityWatch/aw-server-rust#602.
Changed files:
src/util/time.ts— adds three new locale-aware helpers usingIntl.DateTimeFormatsrc/views/Trends.vue— range labels ("Jun 15 – Jul 2") and busiest-day label ("Mon, Jun 15") now use the browser localesrc/visualizations/timeline.ts— event clocktime popup now respects locale time formatNew helpers in
time.ts:format_date_short(date, locale?)— replacesmoment.format('MMM D'), produces e.g. "15 jun" in sv-SEformat_date_with_weekday(date, locale?)— replacesmoment.format('ddd, MMM D'), produces e.g. "mån 15 jun" in sv-SEformat_time_of_day(date, locale?)— replacesmoment.format('HH:mm:ss'), produces 12h or 24h per localeOut of scope (for follow-ups):
periodReadable()week labels in timeperiod.tsThe existing
format_weekday_short,format_day_of_month, andget_short_month_labelsintime.tsalready usedIntl.DateTimeFormat— this PR extends that pattern to the remaining display-facing call sites.Test plan
npm ci && make buildmake lint