Еврейский календарь

Поддержка календарной системы через Intl.DateTimeFormat

В Intl.DateTimeFormat календарная система задаётся через параметр calendar, который входит в набор опций options либо в расширенный BCP 47-идентификатор локали. Еврейский календарь активируется значением:

{ calendar: "hebrew" }

Либо через Unicode extension в строке локали:

"he-IL-u-ca-hebrew"

Ключевой момент заключается в том, что форматирование даты остаётся стандартным с точки зрения API, но все вычисления календарных компонентов (год, месяц, день) переводятся в систему отсчёта, основанную на традиционном еврейском календаре.


Особенности системы летоисчисления

Еврейский календарь является лунно-солнечным, где месяцы основаны на лунных циклах, а годы корректируются солнечными вставками (эмболисмические годы).

Главное отличие от григорианского календаря:

  • отсчёт лет ведётся от традиционной даты сотворения мира (Anno Mundi)
  • год обычно значительно больше привычного григорианского
  • присутствует 12 или 13 месяцев в зависимости от типа года

В JavaScript это отражается исключительно в отображении значений, вычисления остаются абстрагированными внутри движка.


Базовое форматирование даты

const date = new Date("2026-05-27");

const formatter = new Intl.DateTimeFormat("he-IL-u-ca-hebrew", {
  year: "numeric",
  month: "long",
  day: "numeric"
});

formatter.format(date);

Форматирование возвращает строку, где:

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

Структура месяцев

Еврейский календарь включает следующие месяцы:

  • Нисан
  • Ияр
  • Сиван
  • Таммуз
  • Ав
  • Элул
  • Тишрей
  • Хешван
  • Кислев
  • Тевет
  • Шват
  • Адар

В високосные годы добавляется дополнительный месяц — Адар I и Адар II, что создаёт особую структуру отображения при форматировании дат.


Локализация и поведение языков

Локаль he-IL-u-ca-hebrew задаёт не только календарь, но и направление текста и региональные настройки. Однако сам Intl.DateTimeFormat не изменяет язык автоматически при указании календаря.

Пример:

new Intl.DateTimeFormat("en-US-u-ca-hebrew", {
  month: "long",
  year: "numeric"
}).format(new Date());

В результате названия месяцев могут отображаться на английском, но в структуре еврейского календаря.


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

Год в еврейском календаре существенно отличается от григорианского. При использовании numeric или 2-digit:

const f = new Intl.DateTimeFormat("he-IL-u-ca-hebrew", {
  year: "numeric"
});

возвращается значение вида:

  • 5786
  • 5787

Это важно учитывать при:

  • сравнении дат
  • сортировке
  • сохранении в базах данных

Внутренняя модель вычислений

JavaScript не реализует календарные алгоритмы самостоятельно в пользовательском коде. Вместо этого используется ICU (International Components for Unicode), где:

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

Таким образом, Intl работает как слой отображения поверх универсального времени.


День недели и недельные циклы

Еврейский календарь не изменяет стандартную семидневную структуру недели. Однако локаль влияет на:

  • начало недели (в Израиле часто воскресенье или понедельник в зависимости от настроек)
  • отображение названий дней
new Intl.DateTimeFormat("he-IL-u-ca-hebrew", {
  weekday: "long"
}).format(new Date());

Результат зависит от локализации языка, но не от календарной системы.


Использование Intl.Locale

Через Intl.Locale можно явно зафиксировать календарь:

const locale = new Intl.Locale("he-IL", {
  calendar: "hebrew"
});

locale.toString();

Результат:

"he-IL-u-ca-hebrew"

Это позволяет централизованно управлять параметрами локали без ручного формирования строки расширений.


Параметры форматирования и их влияние

Основные опции Intl.DateTimeFormat, влияющие на отображение еврейского календаря:

  • year
  • month
  • day
  • weekday
  • era
  • dateStyle
  • timeStyle

Пример с полным стилем:

new Intl.DateTimeFormat("he-IL-u-ca-hebrew", {
  dateStyle: "full"
}).format(new Date());

Стили (full, long, medium, short) автоматически адаптируют вывод под выбранную календарную систему.


Особенности високосного цикла

В еврейском календаре високосные годы определяются 19-летним циклом Метона. Это приводит к:

  • дополнительному месяцу Адар I
  • смещению дат праздников
  • изменению структуры календарного года

В Intl это не требует ручной обработки — движок автоматически корректирует отображение.


Поведение при сравнении дат

Важно понимать, что Intl.DateTimeFormat не изменяет сам объект Date.

const d = new Date();

d.getFullYear(); // всегда григорианский год

Еврейский календарь применяется только на уровне вывода:

  • сравнение дат остаётся UTC/epoch-based
  • арифметика дат не зависит от календаря
  • только форматирование отражает альтернативную систему

Работа с era (эпохами)

Еврейский календарь использует собственную систему эпохи:

new Intl.DateTimeFormat("he-IL-u-ca-hebrew", {
  year: "numeric",
  era: "short"
}).format(new Date());

Поле era может возвращать обозначения, связанные с традиционной системой летоисчисления, хотя поведение зависит от реализации ICU.


Поведение в разных движках

Реализация зависит от:

  • ICU версии
  • операционной системы
  • браузера или Node.js

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

  • порядок месяцев
  • транслитерация названий
  • поддержка полного набора опций dateStyle

Практическое значение в системах локализации

Еврейский календарь через Intl используется в системах, где требуется:

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

При этом важно, что API не предоставляет прямого доступа к конвертации дат между календарями — только к отображению.


Ограничения модели Intl для еврейского календаря

Несмотря на поддержку, существуют ограничения:

  • отсутствует прямой API для вычисления месяца и года отдельно
  • нет встроенной логики праздников
  • нет календарных правил бизнес-уровня (например, постов или религиозных событий)
  • невозможно получить структуру месяца как массива дат

Intl остаётся системой форматирования, а не календарной логикой.