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

В современной экосистеме JavaScript работа с локализацией и форматированием данных опирается на стандарт ECMA-402, известный как Intl API. Он предоставляет набор объектов для преобразования дат, чисел, валют и строк в формат, соответствующий конкретной языковой и региональной зоне.

Под «зоной» в контексте Intl понимается совокупность параметров отображения: часовой пояс, календарная система, числовой формат, порядок компонентов даты, а также культурные правила округления и группировки. Взаимодействие этих параметров определяет конечное представление данных пользователю.


Каждый форматтер в Intl строится вокруг двух ключевых сущностей:

  • locale — языково-региональный идентификатор (например, en-US, ru-RU, ar-EG)
  • options — объект параметров форматирования

Идентификатор локали задаёт базовые правила отображения, а параметры уточняют поведение.

new Intl.DateTimeFormat("ru-RU", { timeZone: "Europe/Moscow" });

Локаль влияет на порядок элементов, разделители, названия месяцев, систему счисления. Зона времени влияет на вычисление самой даты.


Форматирование дат с учётом временных зон

Intl.DateTimeFormat и timeZone

Ключевым механизмом работы с зонами является параметр timeZone.

const formatter = new Intl.DateTimeFormat("en-GB", {
  timeZone: "Europe/London",
  dateStyle: "full",
  timeStyle: "long"
});

Параметр timeZone принимает IANA-идентификаторы:

  • UTC
  • Europe/Paris
  • Asia/Almaty
  • America/New_York

Без указания зоны используется локальная зона окружения выполнения (браузера или Node.js).


Влияние зоны на результат

Один и тот же timestamp интерпретируется по-разному:

const date = new Date("2026-01-01T12:00:00Z");

new Intl.DateTimeFormat("en-US", {
  timeZone: "America/New_York",
  timeStyle: "short"
}).format(date);

new Intl.DateTimeFormat("en-US", {
  timeZone: "Asia/Tokyo",
  timeStyle: "short"
}).format(date);

Разница формируется исключительно за счёт смещения часового пояса.


Скрытые параметры зоны

Intl учитывает не только явный timeZone, но и дополнительные параметры:

  • hour12 / hourCycle
  • dayPeriod
  • переходы летнего времени (DST)
  • календарные сдвиги

Локализация числовых форматов

Intl.NumberFormat

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

new Intl.NumberFormat("de-DE").format(1234567.89);

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

  • разделителя тысяч
  • десятичного разделителя
  • группировки разрядов

Группировка и система счисления

Параметр numberingSystem позволяет переключать систему записи чисел:

new Intl.NumberFormat("ar-EG-u-nu-arab").format(123456);

Системы включают:

  • латинскую (default)
  • арабскую-индийскую
  • восточноазиатские варианты

Форматирование валют в разных регионах

Intl.NumberFormat с currency

new Intl.NumberFormat("en-US", {
  style: "currency",
  currency: "USD"
}).format(1234.5);

Формат валюты зависит от локали:

  • позиция символа валюты
  • пробел или отсутствие пробела
  • округление

Региональные различия

Одно и то же значение отображается по-разному:

  • en-US: $1,234.50
  • de-DE: 1.234,50 $
  • ja-JP: ¥1,235

Форматирование определяется комбинацией locale + currencyDisplay + rounding rules.


Часовые пояса и календарные системы

calendar как параметр зоны

Intl поддерживает разные календарные системы:

  • григорианский (default)
  • исламский
  • буддийский
  • японский
new Intl.DateTimeFormat("ar-SA-u-ca-islamic", {
  timeZone: "Asia/Riyadh"
});

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

  • номер года
  • структуру месяцев
  • отображение даты

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

Часовой пояс определяет физическое время, календарь — его интерпретацию.

При комбинации:

  • timeZone → вычисляет момент времени
  • calendar → отображает структуру даты

Локали как механизм переключения зон представления

Локаль задаёт сразу несколько слоёв поведения:

  • язык (названия месяцев, дней недели)
  • формат даты
  • правила чисел
  • направление текста (LTR/RTL)
new Intl.DateTimeFormat("he-IL", {
  timeZone: "Asia/Jerusalem"
});

Для арабских и ивритских локалей дополнительно включаются правила:

  • перестановка символов
  • особые числовые системы
  • RTL-выравнивание

Форматирование относительного времени

Intl.RelativeTimeFormat

Используется для отображения времени относительно текущего момента:

new Intl.RelativeTimeFormat("ru-RU").format(-1, "day");

Зоны здесь не участвуют напрямую, но локаль влияет на грамматику:

  • падежи
  • формы множественного числа
  • структура фраз

Детализация параметров форматирования времени

hourCycle и hour12

new Intl.DateTimeFormat("en-US", {
  hour: "2-digit",
  hourCycle: "h23"
});

Возможные варианты:

  • h12 — 12-часовой формат
  • h23 — 24-часовой формат без повторения 0–23
  • h11, h24 — альтернативные системы

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


weekday, year, month, day

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

new Intl.DateTimeFormat("en-CA", {
  weekday: "long",
  year: "numeric",
  month: "long",
  day: "numeric",
  timeZone: "Asia/Shanghai"
});

Комбинация этих параметров создаёт локализованное представление даты.


Нормализация локалей и fallback-цепочки

Intl использует алгоритм:

  1. попытка точного совпадения locale
  2. удаление региональных модификаторов
  3. переход к базовому языку
  4. fallback к дефолтной локали окружения

Пример:

  • fr-CAfren-US

Unicode расширения в локалях

Локали могут содержать расширения -u-, задающие дополнительные параметры:

"en-US-u-ca-buddhist-nu-arab"

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

  • ca — календарь
  • nu — система чисел
  • hc — часовой цикл
  • tz — часовой пояс (в некоторых реализациях)

Эти параметры позволяют кодировать «зону форматирования» внутри самой строки локали.


Влияние окружения выполнения

Результаты Intl зависят от среды:

  • браузер использует ICU из операционной системы
  • Node.js использует встроенный ICU-бандл или системный
  • разные версии ICU дают различия в форматах

Это приводит к тому, что одна и та же локаль может иметь отличия:

  • в названии месяцев
  • в правилах округления
  • в доступных календарях

Композиция форматтеров для комплексных зон

В реальных сценариях используется несколько форматтеров одновременно:

  • DateTimeFormat — дата и время
  • NumberFormat — числа и валюты
  • RelativeTimeFormat — относительные интервалы

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


Изоляция представления данных от бизнес-логики

Intl отделяет вычисление данных от их представления:

  • timestamp остаётся универсальным
  • форматирование зависит от зоны
  • логика приложения не привязана к региону

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