From 6f1232c7334d7c508af4ea238aa1b1a25e25a7f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Bombeck?= Date: Wed, 21 Oct 2026 21:57:04 +0200 Subject: [PATCH] fix(activity): format calendar day keys on their calendar date The week label and each day's accessible name went through the zone-aware formatters, which show a noon-UTC day key as the next day east of UTC+12. Read them in UTC like every other stated date. --- .../activity/activity-calendar-card.tsx | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/components/activity/activity-calendar-card.tsx b/src/components/activity/activity-calendar-card.tsx index b5ec47a75..7e9eef083 100644 --- a/src/components/activity/activity-calendar-card.tsx +++ b/src/components/activity/activity-calendar-card.tsx @@ -86,6 +86,18 @@ export function ActivityCalendarCard() { const query = useActivityCalendar(period, anchor); const data = query.data; const weekdays = useMemo(() => weekdayLabels(locale), [locale]); + // A calendar day key names the same date everywhere: read it in UTC, where + // its noon anchor sits, never in the viewer's zone. + const dayNameFormat = useMemo( + () => + new Intl.DateTimeFormat(locale, { + weekday: "long", + day: "numeric", + month: "long", + timeZone: "UTC", + }), + [locale], + ); const ratedOptions = useMemo(() => { if (!data) return [] as RatedMetric[]; @@ -106,8 +118,8 @@ export function ActivityCalendarCard() { timeZone: "UTC", }).format(dateOfKey(data.start)) : t("activityCalendar.weekRange", { - start: fmt.dateShort(dateOfKey(data.start)), - end: fmt.dateShort(dateOfKey(data.end)), + start: fmt.dateShortSmartCalendar(data.start), + end: fmt.dateShortSmartCalendar(data.end), }) : ""; @@ -126,7 +138,7 @@ export function ActivityCalendarCard() { const levelText = (level: DayLevel) => t(`activityCalendar.level.${level}`); const dayLabel = (day: CalendarDay) => { - const parts = [fmt.dateWithWeekday(dateOfKey(day.date))]; + const parts = [dayNameFormat.format(dateOfKey(day.date))]; if (day.future) return parts.join(", "); if (day.steps !== null) parts.push(