Компоненты FormattedDate, FormattedTime

В библиотеке FormatJS ключевую роль в работе с датами и временем в React-интерфейсах играют компоненты FormattedDate и FormattedTime, предоставляемые через пакет react-intl. Эти компоненты являются декларативной обёрткой над API Intl.DateTimeFormat и позволяют выводить локализованные представления даты и времени без ручного форматирования строк.

Оба компонента ориентированы на интеграцию в React и обеспечивают единообразное отображение временных значений в зависимости от текущей локали, заданной через IntlProvider.


Общая архитектура форматирования дат и времени

В основе компонентов лежит стандарт ECMAScript Internationalization API:

  • Intl.DateTimeFormat — формирование строк даты и времени с учётом локали
  • контекст IntlProvider — источник текущей локали и настроек форматирования
  • декларативный рендеринг — отсутствие необходимости вручную вызывать форматтеры

Компоненты FormattedDate и FormattedTime представляют собой специализированные обёртки, разделяющие ответственность:

  • FormattedDate — работа с календарной датой (день, месяц, год)
  • FormattedTime — работа со временем (часы, минуты, секунды)

FormattedDate

Компонент FormattedDate используется для отображения даты в локализованном формате.

Базовое поведение

При отсутствии дополнительных параметров форматирование полностью определяется текущей локалью:

import { FormattedDate } from "react-intl";

<FormattedDate value={new Date(2026, 0, 15)} />

Результат зависит от языка:

  • en-US → 1/15/2026
  • de-DE → 15.1.2026
  • ru-RU → 15.01.2026

Основной проп value

value принимает:

  • объект Date
  • timestamp (число миллисекунд)
<FormattedDate value={Date.now()} />

Внутри происходит преобразование в Date и передача в Intl.DateTimeFormat.


Управление форматом

Компонент поддерживает стандартные опции Intl.DateTimeFormatOptions.

1. Предустановленные форматы

<FormattedDate
  value={new Date()}
  dateStyle="full"
/>

Возможные значения:

  • full — полное текстовое представление
  • long — расширенный формат
  • medium — стандартный формат
  • short — краткий формат

Пример:

<FormattedDate value={new Date()} dateStyle="full" />

2. Тонкая настройка

Можно задавать отдельные части даты:

<FormattedDate
  value={new Date()}
  year="numeric"
  month="long"
  day="2-digit"
/>

Результат будет зависеть от локали, например:

  • русская локаль → 15 января 2026 г.
  • английская → January 15, 2026

Работа с часовыми поясами

Хотя FormattedDate ориентирован на дату, он наследует поведение Intl.DateTimeFormat, включая timeZone:

<FormattedDate
  value={new Date()}
  timeZone="UTC"
  year="numeric"
  month="2-digit"
  day="2-digit"
/>

Это особенно важно при серверном рендеринге, где локальное время может отличаться от пользовательского.


Использование функции-рендера

Вместо прямого вывода можно использовать render-prop:

<FormattedDate
  value={new Date()}
>
  {(formattedDate) => (
    <span>{formattedDate}</span>
  )}
</FormattedDate>

Это позволяет:

  • внедрять форматированное значение в сложную разметку
  • комбинировать с другими компонентами UI
  • применять дополнительную стилизацию

FormattedTime

FormattedTime отвечает за отображение времени суток.

Базовое использование

import { FormattedTime } from "react-intl";

<FormattedTime value={new Date()} />

Результат:

  • en-US → 3:45 PM
  • ru-RU → 15:45

Проп value

Как и в FormattedDate, принимает:

  • Date
  • timestamp
<FormattedTime value={Date.now()} />

Форматы отображения времени

1. Предустановленные стили

<FormattedTime
  value={new Date()}
  timeStyle="medium"
/>

Поддерживаются:

  • full
  • long
  • medium
  • short

Разница заключается в наличии секунд и формате отображения.


2. Детальная настройка

<FormattedTime
  value={new Date()}
  hour="2-digit"
  minute="2-digit"
  second="2-digit"
/>

Пример вывода:

  • 03:45:12 PM
  • 15:45:12

12-часовой и 24-часовой формат

Формат зависит от локали, но может быть переопределён:

<FormattedTime
  value={new Date()}
  hour="numeric"
  hour12={false}
  minute="2-digit"
/>
  • hour12={false} → принудительно 24-часовой формат

Работа с часовыми поясами

<FormattedTime
  value={new Date()}
  timeZone="Asia/Almaty"
/>

Это гарантирует корректное отображение времени независимо от системного времени пользователя.


Render-prop стиль

<FormattedTime value={new Date()}>
  {(formattedTime) => (
    <time>{formattedTime}</time>
  )}
</FormattedTime>

Используется в случаях:

  • кастомной семантической разметки <time>
  • интеграции с дизайн-системами
  • динамического форматирования UI

Взаимодействие с IntlProvider

Оба компонента зависят от контекста:

import { IntlProvider } from "react-intl";

<IntlProvider locale="ru-RU">
  <App />
</IntlProvider>

Без IntlProvider используется системная локаль браузера, что приводит к непредсказуемому отображению в разных окружениях.


Сравнение FormattedDate и FormattedTime

Область применения

  • FormattedDate:

    • календарные события
    • даты публикаций
    • дедлайны
  • FormattedTime:

    • отметки времени
    • расписания
    • события в реальном времени

Отличия в параметрах

Параметр FormattedDate FormattedTime
year да нет
month да нет
day да нет
hour нет да
minute нет да
second нет да
dateStyle да нет
timeStyle нет да

Поведение при изменении локали

При смене locale в IntlProvider компоненты автоматически перерендериваются:

<IntlProvider locale="fr-FR">

Это приводит к:

  • изменению порядка компонентов даты
  • изменению разделителей
  • адаптации календарных форматов

Особенности серверного рендеринга

При SSR важно учитывать:

  • одинаковую локаль на сервере и клиенте
  • передачу timeZone, если требуется фиксированное значение
  • избежание гидратационных расхождений

Производительность

Компоненты оптимизированы следующим образом:

  • кеширование Intl.DateTimeFormat внутри библиотеки
  • минимизация пересоздания форматтеров
  • отсутствие ручного парсинга дат

Однако частое создание новых Date внутри render-функции может приводить к лишним перерендерингам.


Типичные ошибки использования

  • передача строк вместо Date без явного преобразования
  • отсутствие IntlProvider
  • несогласованность локали между сервером и клиентом
  • попытка использовать компонент как универсальный форматтер без учёта различий date/time

Внутренняя логика форматирования

Оба компонента фактически выполняют следующие шаги:

  1. Получение локали из контекста
  2. Формирование набора опций форматирования
  3. Создание Intl.DateTimeFormat(locale, options)
  4. Применение format(value)
  5. Рендер результата или передача в render-prop

Интеграция в дизайн-системы

Часто используются как базовые строительные блоки:

  • таблицы событий
  • карточки публикаций
  • компоненты логирования действий
  • UI расписаний

Их декларативность делает их предпочтительнее ручного форматирования через утилиты.