Относительное форматирование представляет собой способ отображения времени и величин не в абсолютных значениях, а в контексте текущего момента или другой опорной точки. Вместо фиксированных дат и чисел используются выражения вида «2 минуты назад», «через 3 дня», «прошлой неделе», «в следующем году». Такой подход является частью международных стандартов локализации и широко применяется в пользовательских интерфейсах, где важна мгновенная интерпретация информации без когнитивной нагрузки на преобразование дат.
В экосистеме FormatJS относительное форматирование реализуется как
надстройка над стандартным API JavaScript
Intl.RelativeTimeFormat, а также интегрируется в механизмы
форматирования сообщений ICU MessageFormat через react-intl
и связанные пакеты.
Относительное форматирование опирается на идею измерения разницы между двумя временными точками и преобразования этой разницы в человекочитаемую форму.
Ключевые элементы модели:
Формально значение можно представить как:
delta = targetTime - baseTime
Далее delta нормализуется к выбранной единице
измерения.
Относительное форматирование не просто отображает разницу в миллисекундах, а выбирает наиболее подходящую единицу.
Типичный процесс:
Вычисление разницы в миллисекундах
Последовательное деление на коэффициенты:
Выбор наибольшей единицы, дающей «разумное» число
Пример логики:
Базовый механизм, на котором строится относительное форматирование в Jav * aScript:
const rtf = new Intl.RelativeTimeFormat('ru', { numeric: 'auto' });
rtf.format(-1, 'day'); // "вчера"
rtf.format(-5, 'day'); // "5 дней назад"
rtf.format(2, 'hour'); // "через 2 часа"
locale — язык и регион (ru,
en-US, de)
options.numeric
always — всегда числовой формат («1 день назад»)auto — допускает слова «вчера», «сегодня»,
«завтра»unit — единица времени
В экосистеме FormatJS относительное форматирование интегрируется через несколько уровней:
react-intl позволяет использовать относительное
форматирование прямо в UI-строках:
intl.formatRelativeTime(-3, 'day');
или через декларативные сообщения:
<FormattedRelativeTime value={-2} unit="hour" />
FormatJS использует ICU MessageFormat, где относительные значения могут быть встроены в шаблоны:
{value, relative, unit: "day"}
Такая конструкция позволяет локализациям управлять формой вывода без изменения кода приложения.
Поддерживаемые единицы строго определены спецификацией
Intl.RelativeTimeFormat:
secondminutehourdayweekmonthquarteryearКаждая единица имеет собственные правила склонения и пороговые значения в зависимости от локали.
Главная сложность относительного форматирования заключается не в математике, а в языковой модели.
Например, в русском языке:
В английском:
FormatJS опирается на CLDR (Unicode Common Locale Data Repository), который содержит правила:
Выбор режима влияет на выразительность интерфейса.
Всегда используется числовая форма:
rtf.format(-1, 'day'); // "1 day ago"
Поведение строго и предсказуемо.
Используются естественные выражения:
rtf.format(-1, 'day'); // "yesterday"
rtf.format(0, 'day'); // "today"
rtf.format(1, 'day'); // "tomorrow"
Этот режим улучшает читаемость интерфейсов, ориентированных на человека.
Относительное форматирование включает внутренние правила переключения единиц.
Примеры типичных переходов:
Эти пороги не всегда линейны и могут зависеть от локали и реализации.
В контексте FormatJS относительное форматирование часто используется в UI-слое:
import { FormattedRelativeTime } from 'react-intl';
function CommentTime({ value }) {
return (
<FormattedRelativeTime value={value} unit="minute" />
);
}
Такой подход позволяет:
Относительное форматирование требует строгой нормализации:
Пример:
formatRelativeTime(-10, 'minute'); // 10 минут назад
formatRelativeTime(10, 'minute'); // через 10 минут
Относительное форматирование может выполняться часто (ленты новостей, чаты, уведомления), поэтому важны оптимизации:
Intl.RelativeTimeFormatПример оптимизированного подхода:
const rtfCache = new Map();
function getRtf(locale) {
if (!rtfCache.has(locale)) {
rtfCache.set(locale, new Intl.RelativeTimeFormat(locale));
}
return rtfCache.get(locale);
}
Относительное форматирование не заменяет абсолютное, а дополняет его.
Сравнение:
Выбор зависит от контекста:
Относительное форматирование сталкивается с рядом краевых ситуаций:
В таких случаях FormatJS делегирует поведение
Intl.RelativeTimeFormat, не выполняя дополнительной
семантической интерпретации.
При преобразовании чисел используется округление, обычно к ближайшему целому:
В некоторых реализациях возможны стратегии:
FormatJS следует поведению стандарта ECMAScript, где округление определяется спецификацией API.
Относительное форматирование особенно эффективно в динамических системах:
Причина — естественная интерпретация времени без необходимости точного вычисления даты.
В реальных приложениях относительное форматирование часто комбинируется:
FormatJS позволяет объединять эти форматы через единый слой интернационализации, сохраняя согласованность локализации.
Несмотря на универсальность, относительное форматирование имеет ограничения:
Эти ограничения обусловлены самой природой относительной временной модели, зависящей от текущего момента времени.