Компонент FormattedRelativeTime

FormatJS предоставляет набор инструментов для интернационализации приложений, где компонент FormattedRelativeTime используется для отображения относительного времени в человекочитаемом виде с учётом локали пользователя. В экосистеме React он реализован через react-intl и опирается на нативный Intl.RelativeTimeFormat.

FormattedRelativeTime предназначен для преобразования числового значения и единицы времени в локализованное выражение относительного времени:

  • «5 минут назад»
  • «через 2 дня»
  • «1 час назад»
  • «через 3 месяца»

Компонент автоматически адаптируется под язык и правила форматирования конкретной локали.

Основная задача — устранение ручного формирования строк и делегирование форматирования международному стандарту ICU.

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

Компонент принимает значение времени и единицу измерения, после чего формирует строку относительно текущего момента.

import { FormattedRelativeTime } from "react-intl";

function Example() {
  return (
    <FormattedRelativeTime
      value={-5}
      unit="minute"
    />
  );
}

В данном примере отрицательное значение интерпретируется как прошедшее время.

Логика value и направление времени

Ключевой параметр — value, который задаёт величину интервала.

  • отрицательное значение — прошедшее время
  • положительное значение — будущее время
  • ноль — текущий момент

Примеры:

<FormattedRelativeTime value={-1} unit="day" />
// "вчера" или "1 день назад" (в зависимости от локали)

<FormattedRelativeTime value={2} unit="hour" />
// "через 2 часа"

Важно учитывать, что точное текстовое представление зависит от локали и настроек numeric.

Параметр unit

unit определяет масштаб времени, который используется для интерпретации value.

Поддерживаемые значения:

  • second
  • minute
  • hour
  • day
  • week
  • month
  • quarter
  • year

Пример использования разных единиц:

<FormattedRelativeTime value={30} unit="second" />
<FormattedRelativeTime value={10} unit="minute" />
<FormattedRelativeTime value={3} unit="month" />

Выбор единицы влияет на грамматическую структуру результата и правила округления.

Numeric и текстовые формы

Параметр numeric управляет тем, будет ли вывод строго числовым или допускается словесное выражение.

numeric=“always”

Принудительно использует числовую форму:

<FormattedRelativeTime
  value={-1}
  unit="day"
  numeric="always"
/>

Результат: «1 день назад»

numeric=“auto”

Позволяет использовать языковые формы вроде «вчера», «завтра», если локаль это поддерживает.

<FormattedRelativeTime
  value={-1}
  unit="day"
  numeric="auto"
/>

Результат может быть: «вчера»

Стиль форматирования

Параметр style определяет детализацию вывода:

  • long — полная форма («2 часа назад»)
  • short — сокращённая («2 ч. назад»)
  • narrow — максимально компактная форма («2ч»)

Пример:

<FormattedRelativeTime value={-2} unit="hour" style="long" />
<FormattedRelativeTime value={-2} unit="hour" style="short" />
<FormattedRelativeTime value={-2} unit="hour" style="narrow" />

Выбор стиля зависит от плотности интерфейса.

Поведение обновления во времени

Компонент не является статичным: он может автоматически пересчитывать отображаемое значение при изменении времени.

Внутренне используется таймер обновления, который зависит от величины интервала:

  • секунды обновляются чаще
  • дни и месяцы — реже

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

Связь с Intl.RelativeTimeFormat

FormattedRelativeTime является React-обёрткой над:

Intl.RelativeTimeFormat

Пример низкоуровневого эквивалента:

const rtf = new Intl.RelativeTimeFormat("ru", {
  numeric: "auto",
  style: "long"
});

rtf.format(-1, "day");
// "вчера"

React-компонент автоматизирует:

  • выбор локали из контекста
  • подписку на обновление времени
  • форматирование при изменении props

Использование в контексте IntlProvider

Компонент работает корректно только внутри IntlProvider, который задаёт локаль:

import { IntlProvider } from "react-intl";

<IntlProvider locale="ru">
  <FormattedRelativeTime value={-10} unit="minute" />
</IntlProvider>

Без контекста локали поведение становится неопределённым или fallback-ориентированным.

Округление значений

FormattedRelativeTime не требует передачи идеально нормализованных значений. В некоторых случаях библиотека выполняет внутреннее округление.

Пример:

<FormattedRelativeTime value={90} unit="second" />

Может быть отображено как:

  • «2 минуты назад» (в зависимости от правил локали)

Это связано с тем, что ICU форматтер применяет правила округления и переходов между единицами.

Практика выбора единицы

Выбор unit обычно определяется уровнем детализации данных:

  • события в реальном времени → seconds/minutes
  • пользовательская активность → minutes/hours
  • публикации → hours/days
  • архивные данные → days/months/years

Неправильный выбор единицы приводит к искажению смысла даже при корректном value.

Особенности локализации

Разные языки по-разному выражают относительное время:

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

FormattedRelativeTime полностью делегирует эти правила ICU-данным локали, исключая ручную обработку.

Ограничения компонента

Несмотря на универсальность, существуют ограничения:

  • невозможность кастомизации грамматики вне ICU
  • зависимость от качества локализационных данных
  • отсутствие контекста события (например, «утром», «вечером»)
  • ограниченная точность при нестандартных интервалах

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