Работа с датами в экосистеме FormatJS строится вокруг стандарта ECMA-402 (Intl API) и абстракции над ним, предоставляемой библиотеками семейства, такими как react-intl и низкоуровневые утилиты форматирования. Основная цель — унифицированное представление дат в разных локалях без ручного управления форматами строк.
В JavaScript дата изначально представлена объектом Date,
который хранит количество миллисекунд с 1 января 1970 года (UTC). Однако
отображение даты пользователю зависит от:
FormatJS опирается на Intl.DateTimeFormat, расширяя и
стандартизируя его использование.
Низкоуровневый механизм, который используется внутри FormatJS:
const date = new Date('2026-05-29T12:00:00Z');
const formatter = new Intl.DateTimeFormat('ru-RU', {
year: 'numeric',
month: 'long',
day: 'numeric'
});
formatter.format(date);
Результат зависит от локали:
29 мая 2026 г.
FormatJS использует этот же механизм, но предоставляет декларативный слой поверх него.
Основной способ работы с датами в приложениях на FormatJS —
использование react-intl.
Компонент FormattedDate инкапсулирует
Intl.DateTimeFormat:
import { FormattedDate } from 'react-intl';
function Example() {
const date = new Date('2026-05-29T12:00:00Z');
return (
<FormattedDate
value={date}
year="numeric"
month="long"
day="2-digit"
/>
);
}
Внутри происходит трансформация параметров в конфигурацию
Intl.DateTimeFormat.
useIntlДля более гибкого управления используется хук useIntl,
предоставляющий доступ к методам форматирования.
import { useIntl } from 'react-intl';
function Example() {
const intl = useIntl();
const date = new Date('2026-05-29T12:00:00Z');
const formattedDate = intl.formatDate(date, {
year: 'numeric',
month: 'long',
day: 'numeric'
});
return <div>{formattedDate}</div>;
}
Преимущество этого подхода — возможность динамического формирования формата в логике приложения.
FormatJS полностью зависит от контекста IntlProvider,
который определяет локаль:
import { IntlProvider } from 'react-intl';
<IntlProvider locale="ru">
<App />
</IntlProvider>
Изменение локали автоматически влияет на форматирование всех дат внутри дерева компонентов.
FormatJS позволяет использовать предопределённые стили:
shortmediumlongfullintl.formatDate(date, {
year: 'numeric',
month: 'long',
day: 'numeric',
format: 'long'
});
Пример поведения:
short → 29.05.26medium → 29 мая 2026 г.long → 29 мая 2026 годаfull → пятница, 29 мая 2026 годаЭти стили соответствуют стандартам Intl.DateTimeFormat и
могут быть переопределены через IntlProvider.
Date в FormatJS может включать время:
intl.formatDate(date, {
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit'
});
Результат зависит от локали и часового пояса:
29.05.2026, 15:00
Важно учитывать, что браузер применяет локальный timezone пользователя, если не задан явно.
FormatJS не заменяет Intl, поэтому управление временем
осуществляется через стандартный параметр timeZone:
intl.formatDate(date, {
timeZone: 'UTC',
year: 'numeric',
month: 'long',
day: 'numeric'
});
Это критично для серверных данных, где дата хранится в UTC, но отображается в локальном времени пользователя.
FormatJS широко используется вместе с ICU-сообщениями, где даты вставляются в текстовые шаблоны:
intl.formatMessage(
{
id: 'event.date',
defaultMessage: 'Событие состоится {date}'
},
{
date: intl.formatDate(date, {
year: 'numeric',
month: 'long',
day: 'numeric'
})
}
);
Такой подход обеспечивает отделение текста от локализованных значений дат.
FormatJS поддерживает относительное форматирование через
formatRelativeTime (в зависимости от версии пакета):
intl.formatRelativeTime(-1, 'day');
Результат:
вчера
или
2 дня назад
Относительные даты особенно важны для интерфейсов с динамическими событиями, лентами и уведомлениями.
FormatJS ожидает корректные входные типы:
DateРекомендуется нормализовать данные до объекта Date:
const date = new Date(apiResponse.createdAt);
Ошибки в формате даты приводят к Invalid Date, что
ломает форматирование.
Для масштабируемых приложений применяются централизованные форматы:
const messages = defineMessages({
dateShort: {
id: 'date.short',
defaultMessage: '{date, date, short}'
}
});
И использование:
intl.formatMessage(messages.dateShort, {
date: new Date()
});
Это снижает дублирование конфигураций и упрощает поддержку локализации.
Если IntlProvider не задан, FormatJS использует локаль
браузера:
navigator.language
Это может приводить к непредсказуемому отображению в мультилингвальных приложениях, поэтому явное задание локали является базовым требованием архитектуры.
Форматирование дат через Intl.DateTimeFormat является
дорогостоящей операцией при массовом рендеринге. FormatJS учитывает это
и позволяет:
Пример оптимизированного подхода:
const formatter = new Intl.DateTimeFormat('ru-RU', {
year: 'numeric',
month: 'long',
day: 'numeric'
});
formatter.format(date1);
formatter.format(date2);
В рамках FormatJS это скрыто внутри библиотек, но важно для понимания поведения системы.
При серверном рендеринге (SSR) даты часто сериализуются в строки:
"2026-05-29T12:00:00Z"
На клиенте требуется восстановление:
new Date(serializedDate);
FormatJS не хранит состояние даты, а только форматирует её представление, поэтому корректность восстановления данных определяет итоговый результат отображения.