fix: write calendar dates in the order of the app language

This commit is contained in:
Linus Rath
2026-10-15 04:05:55 +02:00
parent e452f72a8a
commit cf7275c9c3
3 changed files with 42 additions and 3 deletions
+3 -2
View File
@@ -47,6 +47,7 @@ import { editorTimesFromEvent, eventTimeFieldsToSave } from '../../lib/event-edi
import { useSettingsStore } from '../../stores/settings-store';
import { canCreateEventsIn } from '../../lib/calendar-editability';
import { useCalendarLocale } from '../../lib/calendar-locale';
import { formatCalendarDate } from '../../lib/date-format';
import {
alertsToReminders,
remindersToAlerts,
@@ -530,7 +531,7 @@ export function EventModal({
style={styles.dateBtn}
onPress={() => setShowStartDate(true)}
>
<Text style={styles.dateText}>{format(start, 'EEE, MMM d', { locale })}</Text>
<Text style={styles.dateText}>{formatCalendarDate(start, locale.code, 'weekdayMonthDay')}</Text>
</Pressable>
{!allDay && (
<Pressable
@@ -550,7 +551,7 @@ export function EventModal({
style={styles.dateBtn}
onPress={() => setShowEndDate(true)}
>
<Text style={styles.dateText}>{format(end, 'EEE, MMM d', { locale })}</Text>
<Text style={styles.dateText}>{formatCalendarDate(end, locale.code, 'weekdayMonthDay')}</Text>
</Pressable>
{!allDay && (
<Pressable
@@ -0,0 +1,21 @@
import { describe, expect, it } from 'vitest';
import { formatCalendarDate } from '../date-format';
const oct15 = new Date(2026, 9, 15, 10, 0);
describe('formatCalendarDate', () => {
it('puts the day before the month in German', () => {
const s = formatCalendarDate(oct15, 'de', 'weekdayMonthDay');
expect(s).toMatch(/15\. Okt/);
expect(s).not.toMatch(/Okt\.? 15/);
});
it('keeps the US order in English', () => {
expect(formatCalendarDate(oct15, 'en-US', 'weekdayMonthDay')).toBe('Thu, Oct 15');
expect(formatCalendarDate(oct15, 'en', 'monthDayYear')).toBe('Oct 15, 2026');
});
it('names the weekday in full with the year for an all-day date', () => {
expect(formatCalendarDate(oct15, 'de', 'longWeekdayMonthDayYear')).toMatch(/^Donnerstag, 15\. Okt\.? 2026$/);
});
});
+18 -1
View File
@@ -17,7 +17,8 @@ import type { DateFormat, TimeFormat } from '../stores/settings-store';
type Translate = (key: string, fallback?: string, params?: Record<string, string | number>) => string;
type FormatName =
| 'time12' | 'time24' | 'full12' | 'full24' | 'weekday' | 'date' | 'monthDay' | 'monthDayYear';
| 'time12' | 'time24' | 'full12' | 'full24' | 'weekday' | 'date' | 'monthDay' | 'monthDayYear'
| 'weekdayMonthDay' | 'longWeekdayMonthDayYear';
const FORMATS: Record<FormatName, Intl.DateTimeFormatOptions> = {
time12: { hour: '2-digit', minute: '2-digit', hour12: true },
@@ -28,6 +29,8 @@ const FORMATS: Record<FormatName, Intl.DateTimeFormatOptions> = {
date: { year: 'numeric', month: '2-digit', day: '2-digit' },
monthDay: { month: 'short', day: 'numeric' },
monthDayYear: { month: 'short', day: 'numeric', year: 'numeric' },
weekdayMonthDay: { weekday: 'short', month: 'short', day: 'numeric' },
longWeekdayMonthDayYear: { weekday: 'long', month: 'short', day: 'numeric', year: 'numeric' },
};
// Building an Intl formatter is the expensive part of formatting a date (on
@@ -124,3 +127,17 @@ export function formatListDate(
return formatWith(d, intlLocale, 'date');
}
export type CalendarDateStyle = 'weekdayMonthDay' | 'longWeekdayMonthDayYear' | 'monthDay' | 'monthDayYear';
/**
* A calendar date in the order and words of `locale` ("Thu, Oct 15",
* "Do., 15. Okt."). The calendar used fixed US patterns such as
* 'EEE, MMM d', which put German and most other languages in the wrong order.
* `locale` is a language tag such as a date-fns locale's `code`.
*/
export function formatCalendarDate(date: Date, locale: string | undefined, style: CalendarDateStyle): string {
syncFormatterZone(new Date());
const tag = !locale || locale === 'en' ? 'en-US' : locale;
return formatWith(date, tag, style);
}