Конвертация между календарями

Globalize построен поверх CLDR (Unicode Common Locale Data Repository), поэтому работа с календарями в библиотеке опирается не на собственную модель дат, а на стандартизированные локализационные данные. Конвертация между календарями в этом контексте не является прямым преобразованием структуры даты в иной календарный алгоритм, а представляет собой интерпретацию одного и того же момента времени в разных календарных системах, определённых локалью.

CLDR определяет набор календарных систем, включая:

  • григорианский (gregory)
  • исламский (islamic)
  • еврейский (hebrew)
  • буддийский (buddhist)
  • японский (japanese)

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

Ключевой принцип заключается в том, что момент времени остаётся неизменным (timestamp), а меняется лишь способ его отображения.

Представление даты как абсолютного значения

В основе работы лежит UNIX timestamp (миллисекунды с эпохи Unix). Любая дата, независимо от календаря, в конечном итоге сводится к этому числу:

  • 1700000000000 → конкретный момент времени
  • календарь определяет, как этот момент интерпретируется в годах, месяцах и днях

Таким образом, конвертация календарей в Globalize — это не арифметическая операция, а отображение одного и того же timestamp через разные правила форматирования.

Использование CLDR календарных данных

CLDR содержит:

  • правила переходов между годами
  • названия месяцев и дней недели
  • структуру эры (era)
  • смещения календарных систем

Globalize извлекает эти данные через загрузку соответствующих JSON-файлов CLDR, например:

  • ca-gregorian
  • ca-islamic
  • ca-hebrew

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

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

Основной механизм работы — dateFormatter, который использует опцию календаря через locale data.

Пример логики:

  • один и тот же timestamp
  • разные настройки календаря
  • разный вывод строки даты

Внутренне используется:

  • Globalize.dateFormatter(options)
  • CLDR pluralization и naming rules
  • calendar-specific patterns

Пример переключения календарного контекста

При наличии локали, поддерживающей несколько календарей, форматирование может опираться на параметр календаря:

  • gregory: стандартный западный календарь
  • islamic: лунный календарь
  • japanese: система эр императоров

Результат зависит от выбранного набора CLDR-данных, загруженных в runtime.

Принцип псевдоконвертации календарей

Конвертация между календарями в Globalize реализуется через три шага:

1. Нормализация времени

Дата преобразуется в timestamp:

  • вход: “2026-05-27”
  • результат: число миллисекунд

2. Применение календарной системы

Выбирается календарь из CLDR:

  • gregorian
  • islamic-civil
  • hebrew

Каждый календарь имеет собственные алгоритмы разложения timestamp на:

  • год
  • месяц
  • день

3. Локализация вывода

Форматирование производится с учётом:

  • локали (ru, en, ar, he)
  • календаря
  • правил отображения чисел

Ограничения Globalize при работе с календарями

Архитектура накладывает ряд ограничений:

  • отсутствует прямой API вида convertCalendar(date, from, to)
  • нет встроенного механизма изменения календаря объекта Date
  • конвертация всегда опосредована через форматирование

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

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

CLDR хранит альтернативные календарные представления как отдельные наборы правил. Например:

  • ca-islamic-civil — гражданский исламский календарь
  • ca-islamic-umalqura — календарь Умм аль-Кура

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

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

Роль ICU и унификация календарных правил

CLDR основан на ICU (International Components for Unicode), где календарные системы унифицированы через общий интерфейс:

  • календарь как стратегия разбиения времени
  • timestamp как универсальная точка
  • локаль как слой отображения

Globalize следует этой модели, не реализуя собственные календарные вычисления.

Особенности работы с эрой (era)

Некоторые календари используют концепцию эры:

  • японский календарь: Reiwa, Heisei
  • еврейский календарь: Anno Mundi
  • буддийский календарь: отсчёт от нирваны

При форматировании:

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

Взаимодействие с форматами даты и времени

Конвертация календарей тесно связана с форматами:

  • short
  • medium
  • long
  • full

Каждый формат использует разные наборы CLDR-шаблонов, где календарная система влияет на:

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

Интернационализация чисел внутри календарей

Календарная система влияет не только на дату, но и на:

  • систему числовых символов (latn, arab, hanidec)
  • отображение порядковых чисел
  • форматирование годов

Globalize применяет numberingSystem из CLDR совместно с календарными правилами, что приводит к визуально различным представлениям одной и той же даты.

Согласование календаря с локалью

Каждая локаль в CLDR может задавать:

  • основной календарь
  • дополнительные календари
  • приоритет отображения

Globalize использует это при выборе дефолтных настроек форматирования, если календарь явно не указан.

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

Внутренняя модель можно представить как цепочку:

timestamp → CLDR calendar rules → date parts → locale formatting → строка вывода

При этом обратное преобразование (строка → календарь → timestamp) зависит от парсинга и не гарантирует уникальности в альтернативных календарях из-за различий в правилах интерпретации дат.

Обработка неоднозначных дат

В календарях с лунной основой возможны неоднозначности:

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

Globalize избегает разрешения этих конфликтов, полагаясь на уже нормализованные CLDR данные.

Итоговая модель поведения календарной конвертации

С точки зрения архитектуры:

  • календарь не является преобразуемой сущностью
  • календарь — это слой интерпретации timestamp
  • Globalize выполняет только отображение через CLDR

Такой подход обеспечивает согласованность между локалями, но исключает самостоятельную арифметическую конвертацию календарных систем внутри библиотеки.