В основе работы FormatJS с временем лежит стандарт ECMAScript
Internationalization API, а именно Intl.DateTimeFormat.
Этот механизм обеспечивает локализованное форматирование даты и времени
без ручной обработки строковых шаблонов.
Формирование времени опирается на набор параметров:
hour — отображение часаminute — отображение минутsecond — отображение секундhour12 — 12- или 24-часовой форматtimeZone — временная зонаtimeZoneName — отображение названия временной зоныПример базового использования:
const formatter = new Intl.DateTimeFormat('ru-RU', {
hour: '2-digit',
minute: '2-digit'
});
formatter.format(new Date());
FormatJS не заменяет этот механизм, а предоставляет более декларативный слой поверх него, особенно в контексте React и ICU-форматов.
В экосистеме FormatJS ключевую роль играет библиотека
react-intl, которая предоставляет компонентный и
императивный API для работы с локализованным временем.
FormattedTime используется для декларативного
отображения времени в React-компонентах:
import { FormattedTime } from 'react-intl';
<FormattedTime value={new Date()} />
По умолчанию компонент использует настройки локали, заданные в
IntlProvider.
Расширенная конфигурация:
<FormattedTime
value={new Date()}
hour="2-digit"
minute="2-digit"
second="2-digit"
/>
Компонент автоматически адаптируется под локаль пользователя, включая порядок элементов и формат 12/24 часа.
Помимо компонентов, FormatJS предоставляет API через хук
useIntl:
import { useIntl } from 'react-intl';
const Component = () => {
const intl = useIntl();
const timeString = intl.formatTime(new Date(), {
hour: '2-digit',
minute: '2-digit'
});
return <div>{timeString}</div>;
};
Метод formatTime является обёрткой над
Intl.DateTimeFormat, но учитывает контекст локализации
приложения, заданный через провайдер.
FormatJS позволяет задавать именованные форматы, что упрощает единообразное отображение времени в больших приложениях.
Конфигурация задаётся через IntlProvider:
import { IntlProvider } from 'react-intl';
const messages = {};
const formats = {
time: {
short: {
hour: '2-digit',
minute: '2-digit'
},
medium: {
hour: '2-digit',
minute: '2-digit',
second: '2-digit'
},
long: {
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
timeZoneName: 'short'
}
}
};
<IntlProvider locale="ru-RU" messages={messages} formats={formats}>
<App />
</IntlProvider>;
Использование именованного формата:
<FormattedTime value={new Date()} format="short" />
Или через API:
intl.formatTime(date, { format: 'short' });
Такой подход обеспечивает централизованное управление стилями отображения времени.
Работа с временными зонами является критически важной частью
локализации. FormatJS позволяет явно задавать timeZone:
intl.formatTime(new Date(), {
hour: '2-digit',
minute: '2-digit',
timeZone: 'Europe/Moscow'
});
При отсутствии явного указания используется временная зона окружения выполнения (браузера или Node.js).
Особенности:
Date может отображаться по-разному
в разных зонах;Одним из ключевых аспектов локализации времени является выбор между 12- и 24-часовой системой.
intl.formatTime(date, {
hour: '2-digit',
minute: '2-digit',
hour12: true
});
или
intl.formatTime(date, {
hour: '2-digit',
minute: '2-digit',
hour12: false
});
В большинстве случаев hour12 не задаётся явно, так как
система определяется локалью:
en-US → 12-часовой форматru-RU, de-DE, fr-FR →
24-часовой форматFormatJS следует этим правилам автоматически через ICU.
Поддержка секунд зависит от требований интерфейса:
intl.formatTime(date, {
hour: '2-digit',
minute: '2-digit',
second: '2-digit'
});
Хотя Intl.DateTimeFormat не всегда гарантирует поддержку
миллисекунд, некоторые окружения позволяют расширенные настройки через
fractionalSecondDigits:
intl.formatTime(date, {
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
fractionalSecondDigits: 3
});
Такой формат используется в высокоточных интерфейсах, например, логировании событий или мониторинге.
FormatJS полностью полагается на ICU-правила локализации. Это означает, что формат времени может кардинально меняться в зависимости от языка:
:, ., h)Пример:
intl.formatTime(date);
Результаты:
en-US → 3:45 PMru-RU → 15:45fr-FR → 15:45en-GB → 15:45Логика форматирования не зашивается в приложение, а делегируется ICU-данным.
Для сложных интерфейсов, где требуется контроль над каждой частью
строки, используется formatToParts:
intl.formatTimeToParts(date);
Результат:
[
{ type: 'hour', value: '15' },
{ type: 'literal', value: ':' },
{ type: 'minute', value: '30' }
]
Это позволяет:
При серверном рендеринге время может становиться источником несоответствий между сервером и клиентом.
Причины:
Для устранения расхождений фиксируются:
locale в IntlProvidertimeZone в форматирующих функцияхПример стабилизации:
<IntlProvider locale="ru-RU" timeZone="Europe/Moscow">
<App />
</IntlProvider>
Каждый вызов Intl.DateTimeFormat может быть дорогим при
массовом использовании. FormatJS оптимизирует этот процесс за счёт
кэширования форматтеров внутри intl-контекста.
Рекомендации:
Intl.DateTimeFormat вручную в
рендере;intl.formatTime вместо прямого API;formats в
IntlProvider.Разные способы форматирования времени в FormatJS решают разные задачи:
| Подход | Назначение |
|---|---|
<FormattedTime /> |
декларативный React-рендер |
intl.formatTime |
императивная логика |
formats.time |
централизованные стили |
formatToParts |
кастомный рендеринг |
Intl.DateTimeFormat |
низкоуровневый API |
Выбор зависит от уровня контроля над отображением и архитектуры приложения.
FormatJS не отслеживает изменение времени автоматически. Для отображения “живого” времени используется внешнее обновление состояния:
const [now, setNow] = useState(new Date());
useEffect(() => {
const id = setInterval(() => setNow(new Date()), 1000);
return () => clearInterval(id);
}, []);
Далее значение передаётся в FormattedTime или
formatTime.
При передаче невалидного значения Date поведение зависит
от реализации:
Invalid Date может привести к ошибке
форматирования;null и undefined требуют явной
обработки;Корректный подход:
const safeDate = value ? new Date(value) : null;
В крупных приложениях время часто используется в:
Для консистентности применяются единые правила:
short, medium)