fix(time): use Intl numeric day-month-year everywhere so chat day dividers follow the system locale instead of hardcoded English full-month

This commit is contained in:
v.lagerev 2026-05-13 23:30:52 +03:00
parent eb36d8b457
commit 093a908571
4 changed files with 21 additions and 12 deletions

View file

@ -7,7 +7,7 @@ import { getMemberDisplayName, getStateEvent } from '../../utils/room';
import { useMatrixClient } from '../../hooks/useMatrixClient';
import { getMxIdLocalPart, mxcUrlToHttp } from '../../utils/matrix';
import { AsyncStatus, useAsyncCallback } from '../../hooks/useAsyncCallback';
import { timeDayMonthYear, timeHourMinute } from '../../utils/time';
import { timeDayMonYear, timeHourMinute } from '../../utils/time';
import { useRoomNavigate } from '../../hooks/useRoomNavigate';
import { RoomAvatar } from '../room-avatar';
import { nameInitials } from '../../utils/common';
@ -75,7 +75,7 @@ export const RoomIntro = as<'div', RoomIntroProps>(({ room, ...props }, ref) =>
i18nKey="Room.created_by"
values={{
creator: creatorName,
date: timeDayMonthYear(ts),
date: timeDayMonYear(ts),
time: timeHourMinute(ts),
}}
components={{ bold: <b /> }}

View file

@ -105,7 +105,7 @@ import { markAsRead } from '../../utils/notifications';
import { useDebounce } from '../../hooks/useDebounce';
import { getResizeObserverEntry, useResizeObserver } from '../../hooks/useResizeObserver';
import * as css from './RoomTimeline.css';
import { inSameDay, minuteDifference, timeDayMonthYear, today, yesterday } from '../../utils/time';
import { inSameDay, minuteDifference, timeDayMonYear, today, yesterday } from '../../utils/time';
import { isEmptyEditor } from '../../components/editor';
import { draftKey, roomIdToReplyDraftAtomFamily } from '../../state/room/roomInputDrafts';
import { usePowerLevelsContext } from '../../hooks/usePowerLevels';
@ -2211,7 +2211,7 @@ export function RoomTimeline({
const dayLabel = (() => {
if (today(mEvent.getTs())) return t('Room.today');
if (yesterday(mEvent.getTs())) return t('Room.yesterday');
return timeDayMonthYear(mEvent.getTs());
return timeDayMonYear(mEvent.getTs());
})();
const renderDayDivider = () => (

View file

@ -28,7 +28,7 @@ import { useAlive } from '../../../hooks/useAlive';
import { useStateEvent } from '../../../hooks/useStateEvent';
import { useRoom } from '../../../hooks/useRoom';
import { StateEvent } from '../../../../types/matrix/room';
import { getToday, getYesterday, timeDayMonthYear, timeHourMinute } from '../../../utils/time';
import { getToday, getYesterday, timeDayMonYear, timeHourMinute } from '../../../utils/time';
import { DatePicker, TimePicker } from '../../../components/time-date';
type JumpToTimeProps = {
@ -168,7 +168,7 @@ export function JumpToTime({ onCancel, onSubmit }: JumpToTimeProps) {
after={<Icon size="50" src={Icons.ChevronBottom} />}
onClick={handleDatePicker}
>
<Text size="B300">{timeDayMonthYear(ts)}</Text>
<Text size="B300">{timeDayMonYear(ts)}</Text>
</Chip>
<PopOut
anchor={datePickerCords}

View file

@ -26,9 +26,20 @@ const detectSystemHour24 = (): boolean => {
export const SYSTEM_HOUR_24: boolean = detectSystemHour24();
// 24-hour systems get the European day-month-year layout; 12-hour systems get
// the American month-day-year layout.
const SYSTEM_DAY_MON_YEAR_FORMAT = SYSTEM_HOUR_24 ? 'DD/MM/YYYY' : 'MM/DD/YYYY';
// Locale picks its own day-month-year order and separator: de-DE/ru-RU yield
// "13.05.2026", en-GB "13/05/2026", en-US "05/13/2026". Built once at module
// load — locale doesn't change without a page reload.
const dayMonYearFormatter: Pick<Intl.DateTimeFormat, 'format'> = (() => {
try {
return new Intl.DateTimeFormat(undefined, {
day: '2-digit',
month: '2-digit',
year: 'numeric',
});
} catch {
return { format: (date: Date) => dayjs(date).format('DD.MM.YYYY') };
}
})();
export const today = (ts: number): boolean => dayjs(ts).isToday();
@ -45,9 +56,7 @@ export const timeYear = (ts: number): string => dayjs(ts).format('YYYY');
export const timeHourMinute = (ts: number): string =>
dayjs(ts).format(SYSTEM_HOUR_24 ? 'HH:mm' : 'hh:mm A');
export const timeDayMonYear = (ts: number): string => dayjs(ts).format(SYSTEM_DAY_MON_YEAR_FORMAT);
export const timeDayMonthYear = (ts: number): string => dayjs(ts).format('D MMMM YYYY');
export const timeDayMonYear = (ts: number): string => dayMonYearFormatter.format(new Date(ts));
export const daysInMonth = (month: number, year: number): number =>
dayjs(`${year}-${month}-1`).daysInMonth();