Форматирование дат и времени

Объект Intl.DateTimeFormat предоставляет стандартизированный механизм локализованного форматирования дат и времени. Его ключевая задача — преобразование объектов Date в строковое представление, соответствующее правилам конкретного языка, региона и культурных предпочтений.

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

  • локальные порядки компонентов даты;
  • особенности календарей;
  • различные форматы времени (12/24 часа);
  • правила отображения часовых поясов.
const formatter = new Intl.DateTimeFormat('ru-RU');

formatter.format(new Date());

Локаль и её влияние на форматирование

Первый аргумент Intl.DateTimeFormat определяет локаль. Она влияет на порядок элементов даты, используемые разделители и словесные обозначения.

new Intl.DateTimeFormat('en-US').format(new Date());
// 12/26/2026

new Intl.DateTimeFormat('de-DE').format(new Date());
// 26.12.2026

new Intl.DateTimeFormat('ja-JP').format(new Date());
// 2026/12/26

Поддерживаются также составные локали с региональными модификаторами:

new Intl.DateTimeFormat('en-GB').format(new Date());
// 26/12/2026

Базовые стили форматирования

Второй параметр конструктора определяет стиль отображения компонентов даты и времени. Основные категории:

  • short
  • medium
  • long
  • full
const d = new Date();

new Intl.DateTimeFormat('ru-RU', { dateStyle: 'short' }).format(d);
new Intl.DateTimeFormat('ru-RU', { dateStyle: 'medium' }).format(d);
new Intl.DateTimeFormat('ru-RU', { dateStyle: 'long' }).format(d);
new Intl.DateTimeFormat('ru-RU', { dateStyle: 'full' }).format(d);

Для времени аналогично:

new Intl.DateTimeFormat('ru-RU', { timeStyle: 'short' }).format(d);
new Intl.DateTimeFormat('ru-RU', { timeStyle: 'medium' }).format(d);
new Intl.DateTimeFormat('ru-RU', { timeStyle: 'long' }).format(d);
new Intl.DateTimeFormat('ru-RU', { timeStyle: 'full' }).format(d);

Комбинация dateStyle и timeStyle задаёт единый формат даты и времени.


Управление отдельными компонентами даты

Более точная настройка достигается через набор опций:

  • year
  • month
  • day
  • weekday
  • hour
  • minute
  • second
  • timeZoneName
new Intl.DateTimeFormat('ru-RU', {
  year: 'numeric',
  month: 'long',
  day: '2-digit'
}).format(new Date());

Варианты значений:

  • numeric — числовое представление
  • 2-digit — фиксированная длина с ведущим нулём
  • long — полное название
  • short — сокращённая форма (для месяцев, дней недели)

Форматирование дня недели

new Intl.DateTimeFormat('ru-RU', {
  weekday: 'long',
  year: 'numeric',
  month: 'long',
  day: 'numeric'
}).format(new Date());

Добавление weekday расширяет контекст даты и используется в интерфейсах календарей и расписаний.


Формат времени и 12/24-часовой режим

Опция hour12 управляет форматом времени:

new Intl.DateTimeFormat('en-US', {
  hour: '2-digit',
  minute: '2-digit',
  hour12: true
}).format(new Date());
new Intl.DateTimeFormat('ru-RU', {
  hour: '2-digit',
  minute: '2-digit',
  hour12: false
}).format(new Date());

Автоматическое поведение зависит от локали, но явное указание переопределяет его.


Часовые пояса и их влияние

Опция timeZone задаёт конкретный часовой пояс, независимо от локальной системы.

new Intl.DateTimeFormat('ru-RU', {
  timeZone: 'UTC',
  year: 'numeric',
  month: '2-digit',
  day: '2-digit',
  hour: '2-digit',
  minute: '2-digit'
}).format(new Date());

Используются IANA-идентификаторы:

  • Europe/Moscow
  • Asia/Almaty
  • America/New_York

Отображение названия часового пояса

new Intl.DateTimeFormat('ru-RU', {
  timeZoneName: 'short'
}).format(new Date());

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

  • short — сокращённый формат (например, GMT+3)
  • long — полное описание (например, Moscow Standard Time)

Разделение результата на части

Метод formatToParts возвращает структурированное представление результата форматирования. Это позволяет работать с компонентами даты отдельно.

const formatter = new Intl.DateTimeFormat('ru-RU', {
  year: 'numeric',
  month: '2-digit',
  day: '2-digit'
});

formatter.formatToParts(new Date());

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

[
  { type: 'day', value: '26' },
  { type: 'literal', value: '.' },
  { type: 'month', value: '12' },
  { type: 'literal', value: '.' },
  { type: 'year', value: '2026' }
]

Это используется для:

  • кастомного UI календарей;
  • подсветки отдельных частей даты;
  • интернационализированных компонентов интерфейса.

Получение итоговой конфигурации форматтера

Метод resolvedOptions возвращает фактические параметры, применённые движком после нормализации:

const formatter = new Intl.DateTimeFormat('ru-RU', {
  year: 'numeric',
  month: 'long'
});

formatter.resolvedOptions();

Типичные поля результата:

  • locale
  • calendar
  • numberingSystem
  • timeZone
  • hour12

Календарные системы

Intl.DateTimeFormat поддерживает различные календари через параметр calendar.

new Intl.DateTimeFormat('ar-EG-u-ca-islamic', {
  day: 'numeric',
  month: 'long',
  year: 'numeric'
}).format(new Date());

Распространённые системы:

  • gregory (григорианский)
  • islamic
  • japanese
  • buddhist

Календарь влияет на:

  • систему летоисчисления;
  • названия месяцев;
  • отображение года.

Системы счисления

Опция numberingSystem задаёт формат цифр.

new Intl.DateTimeFormat('ar-EG', {
  numberingSystem: 'arab'
}).format(new Date());

Поддерживаемые системы:

  • latn (латинская)
  • arab
  • hanidec

Это влияет на визуальное представление чисел в дате.


Комбинированные конфигурации форматирования

Комплексные настройки позволяют формировать локализованные строки высокой точности:

new Intl.DateTimeFormat('ru-RU', {
  weekday: 'long',
  year: 'numeric',
  month: 'long',
  day: 'numeric',
  hour: '2-digit',
  minute: '2-digit',
  second: '2-digit',
  timeZone: 'Europe/Moscow',
  timeZoneName: 'short'
}).format(new Date());

Такие конфигурации применяются в:

  • календарных интерфейсах;
  • системах бронирования;
  • финансовых приложениях;
  • логировании событий.

Повторное использование форматтера

Объект Intl.DateTimeFormat оптимизирован для повторного использования. Создание нового экземпляра требует вычислений локали и правил форматирования, поэтому практикуется кэширование:

const formatter = new Intl.DateTimeFormat('ru-RU', {
  year: 'numeric',
  month: '2-digit',
  day: '2-digit'
});

function format(date) {
  return formatter.format(date);
}

Поведение при отсутствии опций

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

new Intl.DateTimeFormat().format(new Date());

Поведение зависит от окружения выполнения:

  • браузера;
  • Node.js;
  • системной локали.

Особенности нормализации параметров

Некоторые комбинации опций приводят к автоматической корректировке:

  • несовместимые стили игнорируются;
  • часть параметров приводится к стандартному виду;
  • локаль может переопределять формат времени.
new Intl.DateTimeFormat('ru-RU', {
  hour: 'numeric',
  year: 'numeric',
  dateStyle: 'full'
});

В подобных случаях приоритет имеют dateStyle и timeStyle.


Различия между форматированием и локализацией логики

Форматирование через Intl.DateTimeFormat не изменяет сам объект Date. Все операции выполняются только на уровне представления:

  • исходное время остаётся неизменным;
  • вычисления не зависят от локали;
  • различия проявляются только в строковом выводе.
const date = new Date();

date.getTime(); // одинаковое значение для всех локалей

Ограничения и предсказуемость вывода

Результат форматирования зависит от:

  • версии ICU в окружении;
  • настроек системы;
  • поддержки локалей;
  • часовых поясов.

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


Использование в связке с другими Intl API

Форматирование дат часто комбинируется с:

  • Intl.NumberFormat для числовых компонентов;
  • Intl.RelativeTimeFormat для относительных дат;
  • Intl.Locale для анализа локали.

Однако Intl.DateTimeFormat остаётся основным инструментом для абсолютного представления даты и времени в локализованном виде.