fix(dates): make DAY precision locale-aware in formatDocumentDate

DAY precision routed through formatDate() which hard-coded de-DE, so an
en/es reader saw the German month name ("24. Dezember 1943"). Route DAY
through Intl.DateTimeFormat(locale, …) like the other branches, keeping
the T12:00:00 UTC-safety convention. Add en/es DAY+MONTH parity cases to
docs/date-label-fixtures.json (TS-only; the Java title formatter stays
German by design) and assert them in the spec.

Refs #666

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Marcel
2026-05-27 12:19:09 +02:00
parent b1b8fa4bed
commit 8ed5b1e9e3
3 changed files with 110 additions and 7 deletions

View File

@@ -1,4 +1,4 @@
import { formatDate, formatMCDate } from './date';
import { formatMCDate } from './date';
import { m } from '$lib/paraglide/messages.js';
/**
@@ -10,9 +10,11 @@ export type DatePrecision = 'DAY' | 'MONTH' | 'SEASON' | 'YEAR' | 'RANGE' | 'APP
/**
* Renders a document date at exactly the precision the data claims — never finer.
*
* Delegates to the {@link formatDate}/{@link formatMCDate} helpers (so the
* `T12:00:00` UTC-safety convention and the German Intl formatting are shared,
* not reimplemented) and routes every localized word through Paraglide.
* Every structured part (month name, day-of-month text, season word, prefixes)
* is rendered in the active `locale` — DAY, MONTH and RANGE all go through
* `Intl.DateTimeFormat(locale, …)` and the localized words through Paraglide
* so an `en`/`es` reader never sees a German month name. The `T12:00:00`
* UTC-safety convention is kept via {@link noon}.
*
* The label is the SINGLE SOURCE OF TRUTH shared with the Java
* {@code DocumentTitleFormatter}: both are asserted against
@@ -42,7 +44,7 @@ export function formatDocumentDate(
switch (precision) {
case 'DAY':
return formatDate(iso, 'long');
return longDate(iso, locale);
case 'MONTH':
return monthYear(iso, locale);
case 'SEASON':
@@ -60,6 +62,14 @@ export function formatDocumentDate(
// ─── precision branches ──────────────────────────────────────────────────────
function longDate(iso: string, locale: string): string {
return new Intl.DateTimeFormat(locale, {
day: 'numeric',
month: 'long',
year: 'numeric'
}).format(noon(iso));
}
function monthYear(iso: string, locale: string): string {
return new Intl.DateTimeFormat(locale, { month: 'long', year: 'numeric' }).format(noon(iso));
}