Названия календарей

Календарная система в ECMAScript Internationalization API определяется через Unicode Locale Identifier и параметр calendar, который влияет на то, как формируются и интерпретируются даты в локализованных форматах. В основе лежит стандарт Unicode CLDR, где каждая календарная система имеет строковый идентификатор и может быть выбрана как часть языкового тега.

В спецификации Intl календарь не является отдельной сущностью уровня приложения — он встроен в локаль через расширение Unicode -u-ca-.

Структура тега локали:

language[-script][-region]-u-ca-calendar

Пример:

const locale = "ar-EG-u-ca-islamic";

Здесь:

  • ar-EG — арабский язык, Египет
  • u-ca-islamic — исламский календарь

Это расширение влияет на поведение всех API, работающих с датами.

Основные идентификаторы календарей

В Intl используются стандартизированные строки календарных систем. Они соответствуют Unicode CLDR:

  • gregory — григорианский календарь (де-факто стандарт)
  • buddhist — буддийский календарь (используется в Таиланде)
  • chinese — китайский лунно-солнечный календарь
  • coptic — коптский календарь
  • ethiopic — эфиопский календарь
  • hebrew — еврейский календарь
  • indian — индийский национальный календарь
  • islamic — исламский (лунный) календарь
  • islamic-umalqura — модифицированный исламский календарь (Умм аль-Кура)
  • iso8601 — ISO календарная система
  • japanese — японский календарь эпох
  • persian — персидский календарь
  • roc — календарь Республики Китай

Эти значения используются как в параметрах API, так и в расширениях локали.

Использование календаря в Intl.DateTimeFormat

Календарная система задаётся через опцию calendar:

const fmt = new Intl.DateTimeFormat("en-US", {
  calendar: "islamic"
});

console.log(fmt.format(new Date()));

Форматирование даты остаётся локализованным, но система отсчёта лет и месяцев изменяется в соответствии с выбранным календарём.

При этом сам язык форматирования (например, названия месяцев) определяется локалью "en-US", а не календарём.

Влияние календаря на вывод дат

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

const d = new Date(2026, 0, 1);

console.log(new Intl.DateTimeFormat("en-US", {
  calendar: "gregory",
  year: "numeric",
  month: "long",
  day: "numeric"
}).format(d));

console.log(new Intl.DateTimeFormat("en-US", {
  calendar: "islamic",
  year: "numeric",
  month: "long",
  day: "numeric"
}).format(d));

В первом случае используется привычный год 2026, во втором — другой календарный отсчёт, соответствующий исламской системе летоисчисления.

Unicode extension ca в строке локали

Календарь можно задать не только через Intl.DateTimeFormat, но и через саму локаль:

const dtf = new Intl.DateTimeFormat("th-TH-u-ca-buddhist", {
  year: "numeric",
  month: "long",
  day: "numeric"
});

Здесь:

  • th-TH — тайский язык и регион
  • u-ca-buddhist — буддийский календарь

Этот способ считается более декларативным, поскольку календарь становится частью идентификатора локали, а не параметром форматирования.

Intl.Locale и календарные системы

Объект Intl.Locale предоставляет структурированный доступ к компонентам локали, включая календарь.

const loc = new Intl.Locale("ja-JP-u-ca-japanese");

console.log(loc.calendar); // "japanese"

Можно также программно формировать локаль:

const loc = new Intl.Locale("en-US", {
  calendar: "hebrew"
});

console.log(loc.toString());

Результирующая локаль будет содержать расширение -u-ca-hebrew.

Получение поддерживаемых календарей

Современные реализации ECMAScript предоставляют метод:

Intl.supportedValuesOf("calendar");

Он возвращает список календарных систем, поддерживаемых окружением:

[
  "buddhist",
  "chinese",
  "coptic",
  "dangi",
  "ethiopic",
  "gregory",
  "hebrew",
  "indian",
  "islamic",
  "islamic-civil",
  "islamic-rgsa",
  "islamic-tbla",
  "islamic-umalqura",
  "iso8601",
  "japanese",
  "persian",
  "roc"
]

Наличие конкретных значений зависит от реализации движка JavaScript и данных ICU.

Календарь и внутреннее представление даты

Важно различать:

  • Date в JavaScript всегда хранит время в виде Unix timestamp (миллисекунды от эпохи Unix)
  • календарь применяется только на этапе форматирования

Это означает, что:

const d = new Date("2026-05-01T00:00:00Z");

не меняется при смене календаря. Меняется только интерпретация при выводе.

Локализация эпох и специфические календари

Некоторые календари вводят дополнительные элементы, не существующие в григорианской системе:

Японский календарь (japanese)

Использует эпохи правления императоров:

new Intl.DateTimeFormat("ja-JP", {
  calendar: "japanese",
  year: "numeric",
  era: "short",
  month: "numeric",
  day: "numeric"
}).format(new Date());

Вывод может включать обозначение эпохи вроде Reiwa.

Китайский календарь (chinese)

Может включать циклы и лунные элементы, но в Intl обычно сводится к году и месяцу по лунно-солнечной системе.

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

Если календарь не соответствует культурной локали, Intl не выдаёт ошибку. Вместо этого:

  • используются числовые значения, адаптированные под календарь
  • локализация текстовых элементов остаётся от базовой локали

Пример:

new Intl.DateTimeFormat("fr-FR", {
  calendar: "islamic"
});

Французский язык остаётся французским, но календарная система меняется.

Календарь в сочетании с другими параметрами форматирования

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

  • год (year)
  • месяц (month)
  • эпоху (era)

Но не влияет напрямую на:

  • формат времени (hour, minute, second)
  • часовой пояс (timeZone)

Пример комбинированного использования:

new Intl.DateTimeFormat("en-US", {
  calendar: "persian",
  timeZone: "Asia/Tehran",
  year: "numeric",
  month: "long",
  day: "numeric",
  hour: "2-digit",
  minute: "2-digit"
});

Здесь календарь определяет систему летоисчисления, а часовой пояс — смещение времени.

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

Реализация календарей в JavaScript опирается на библиотеку ICU (International Components for Unicode). Именно ICU определяет:

  • поддержку конкретных календарей
  • правила преобразования дат
  • локализацию названий месяцев и эпох

Поэтому различия между окружениями (Node.js, браузеры) возможны при устаревших версиях ICU.

Влияние на сортировку и сравнение дат

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

  • сравнение Date объектов
  • арифметику дат
  • сортировку временных значений
const a = new Date("2026-01-01");
const b = new Date("2026-12-31");

console.log(a < b); // true

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

Практическое значение календарных систем

Календарные системы в Intl используются в основном для:

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

При этом внутренняя логика приложений почти всегда остаётся на григорианской системе, а альтернативные календари применяются только на уровне представления данных.