Skip to content

fix(timeline): localize chart date labels#825

Open
TimeToBuildBob wants to merge 2 commits into
ActivityWatch:masterfrom
TimeToBuildBob:bob/locale-timeline-labels
Open

fix(timeline): localize chart date labels#825
TimeToBuildBob wants to merge 2 commits into
ActivityWatch:masterfrom
TimeToBuildBob:bob/locale-timeline-labels

Conversation

@TimeToBuildBob
Copy link
Copy Markdown
Contributor

Summary

  • remove hardcoded English weekday and month labels from TimelineBarChart
  • use locale-aware helpers for weekly, monthly, and yearly chart labels
  • cover the new helpers with a focused unit test

Testing

  • npm test -- --runInBand test/unit/time.test.js

Context

This fixes the locale inconsistency reported in ActivityWatch/aw-server-rust#602. The UI lives in aw-webui, so I am landing the frontend change here first and linking the parent issue back to this PR.

@codecov
Copy link
Copy Markdown

codecov Bot commented May 19, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 31.32%. Comparing base (b8ec3c0) to head (53c16c2).

Additional details and impacted files
@@            Coverage Diff             @@
##           master     #825      +/-   ##
==========================================
+ Coverage   31.01%   31.32%   +0.30%     
==========================================
  Files          34       34              
  Lines        1996     2005       +9     
  Branches      354      354              
==========================================
+ Hits          619      628       +9     
  Misses       1356     1356              
  Partials       21       21              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented May 19, 2026

Greptile Summary

This PR removes hardcoded English weekday and month labels from TimelineBarChart and replaces them with Intl.DateTimeFormat-backed helpers (format_weekday_short, format_day_of_month, get_short_month_labels) in src/util/time.ts, so chart axis labels now follow the user's browser locale.

  • TimelineBarChart.vue replaces static string arrays and the custom ordinal-suffix logic with the new helpers; the weekly branch gains a setHours(12, 0, 0, 0) call before day arithmetic to guard against DST edge cases.
  • Three unit tests are added covering locale differentiation for each helper, though most assertions are tautological (verifying delegation to Intl) — the cross-locale inequality checks are the meaningful ones.
  • A private normalize_date helper is introduced that only clones a Date with getTime(); since Intl.DateTimeFormat.format() never mutates its argument, the copy is not needed and the name implies a transformation that doesn't occur.

Confidence Score: 5/5

Safe to merge; changes are confined to label formatting logic and introduce no data-path or behavioral regressions.

All chart-label paths that previously used hardcoded English strings now delegate to Intl.DateTimeFormat with undefined locale (browser default), which is the correct approach. The weekly branch correctly anchors dates to local noon before day arithmetic. No existing logic is removed or altered beyond the label-generation step.

No files require special attention.

Important Files Changed

Filename Overview
src/util/time.ts Adds three locale-aware date-formatting helpers plus a private normalize_date clone helper that is unnecessary since Intl.DateTimeFormat.format() never mutates its argument.
src/visualizations/TimelineBarChart.vue Replaces hardcoded English weekday/month arrays with locale-aware helpers; adds setHours(12,0,0,0) before day arithmetic in the weekly branch to guard against DST edge cases.
test/unit/time.test.js Adds focused unit tests for the three new helpers; core assertions are largely tautological, but the cross-locale inequality checks verify runtime locale differentiation.

Reviews (2): Last reviewed commit: "fix(timeline): remove unsafe date label ..." | Re-trigger Greptile

Comment thread src/util/time.ts Outdated
Comment on lines +9 to +11
function normalize_date(dateParam: Date | string) {
return dateParam instanceof Date ? new Date(dateParam.getTime()) : new Date(dateParam);
}
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.

P2 Date-only strings silently shift to wrong day in non-UTC timezones

new Date("2023-03-12") (ISO 8601 date-only) is parsed as UTC midnight per spec. When Intl.DateTimeFormat later formats that Date in the user's local timezone — say UTC-5 — it sees March 11 at 19:00 and renders Saturday instead of Sunday. Any caller who passes a date string like timeperiod_start directly to format_weekday_short or format_month_day will get the wrong label in any non-UTC timezone. The current Vue callers all pass Date objects with the time pre-set to local noon, so they are unaffected — but the exported API silently creates this footgun. Consider documenting that string inputs with date-only format are unsafe, or restricting the parameter type to Date.

Comment thread src/util/time.ts Outdated
Comment on lines +106 to +108
export function format_month_day(dateParam: Date | string, locale?: string | string[]) {
return new Intl.DateTimeFormat(locale, { day: 'numeric' }).format(normalize_date(dateParam));
}
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.

P2 Misleading function name — only formats the day, not month+day

format_month_day implies a combined month-and-day output (e.g., "May 1"), but the formatter only uses { day: 'numeric' }, returning "1", "2", etc. The name could confuse a future caller expecting a month component. format_day_of_month or format_day_numeric would be more accurate.

Suggested change
export function format_month_day(dateParam: Date | string, locale?: string | string[]) {
return new Intl.DateTimeFormat(locale, { day: 'numeric' }).format(normalize_date(dateParam));
}
export function format_day_of_month(dateParam: Date | string, locale?: string | string[]) {
return new Intl.DateTimeFormat(locale, { day: 'numeric' }).format(normalize_date(dateParam));
}

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

@TimeToBuildBob
Copy link
Copy Markdown
Contributor Author

✅ CI green, Greptile 5/5, all checks passing. Merge-ready — waiting on maintainer merge click.

Summary: Hardcoded English weekday/month labels in TimelineBarChart replaced with Intl.DateTimeFormat-backed locale-aware helpers, with DST edge case guard and covered integration tests.

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.

1 participant