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

Архитектура календарей в CLDR и роль Globalize

Поддержка календарей в Globalize основана на данных CLDR (Unicode Common Locale Data Repository), где календарь рассматривается как набор правил отображения и вычисления дат для конкретной культурной традиции. В рамках CLDR китайский календарь представлен как chinese и относится к лунно-солнечным системам летоисчисления, включающим циклическую структуру лет, месяцев и вставных месяцев.

Globalize не реализует календарные алгоритмы самостоятельно. Библиотека выступает как слой доступа к стандартизированным данным CLDR, обеспечивая форматирование и парсинг дат через унифицированный API.

Китайский календарь в CLDR характеризуется следующими особенностями:

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

Подключение и подготовка данных CLDR

Работа с китайским календарём требует загрузки соответствующих данных CLDR, включая числа, даты, календари и временные форматы.

import Globalize from "globalize";
import likelySubtags from "cldr-core/supplemental/likelySubtags.json";
import numbers from "cldr-numbers-full/main/zh/numbers.json";
import timeData from "cldr-dates-full/main/zh/ca-chinese.json";
import calendarData from "cldr-dates-full/main/zh/ca-gregorian.json";
import timeZoneNames from "cldr-dates-full/main/zh/timeZoneNames.json";
import weekData from "cldr-core/supplemental/weekData.json";

Инициализация CLDR в Globalize:

Globalize.load(
  likelySubtags,
  numbers,
  timeData,
  calendarData,
  timeZoneNames,
  weekData
);

Globalize.locale("zh");

Ключевым моментом является наличие блока ca-chinese.json, который содержит правила китайского календаря.


Концепция китайского календаря в Globalize

Китайский календарь в CLDR не является прямой заменой григорианского, а существует как альтернативное представление даты.

Основные уровни представления:

  • solar: григорианская система (по умолчанию)
  • chinese: лунно-солнечная система
  • buddhist: буддийский календарь (для сравнения)

Globalize позволяет переключаться между форматами отображения без изменения исходного timestamp.


Форматирование дат в китайском календаре

Форматирование осуществляется через Globalize.dateFormatter, где выбор календаря происходит через параметры формата.

const globalize = new Globalize("zh");

const formatter = globalize.dateFormatter({
  datetime: "medium",
  calendar: "chinese"
});

const date = new Date(2026, 0, 29);

formatter(date);

Результат формируется на основе правил CLDR и может включать:

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

Структура календарных символов

CLDR описывает китайский календарь через набор локализованных символов:

  • cyclicName — циклическое имя года
  • month — лунный месяц
  • day — день месяца
  • era — эра (династическая или общая система)

Пример доступа к данным через Globalize:

const cldr = Globalize.cldr;

cldr.main("dates/calendars/chinese/months");

Данные возвращаются в виде структурированных JSON-объектов, где каждая единица локализована.


Парсинг дат в китайском календаре

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

const parser = globalize.dateParser({
  calendar: "chinese"
});

parser("2026年正月初一");

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


Форматы отображения компонентов даты

Globalize использует стандартные шаблоны CLDR:

  • full
  • long
  • medium
  • short

Для китайского календаря эти форматы дополняются культурными обозначениями:

globalize.dateFormatter({
  date: "full",
  calendar: "chinese"
});

Пример структуры формата:

  • год: циклический + числовой
  • месяц: порядковый + название
  • день: числовой + контекст сезона

Взаимодействие с григорианским календарём

Globalize всегда хранит исходное значение даты в виде timestamp (Unix epoch), а календарь выступает слоем представления.

Сравнение:

const g = new Globalize("zh");

const gregorian = g.dateFormatter({ date: "medium" });
const chinese = g.dateFormatter({ date: "medium", calendar: "chinese" });

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

gregorian(d);
chinese(d);

Различие проявляется только на уровне отображения, не затрагивая внутреннее значение даты.


Работа с лунными циклами

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

  • isLeapMonth — признак високосного месяца
  • monthCode — код месяца в цикле
  • yearCycle — позиция в 60-летнем цикле

Эти значения доступны через расширенные API CLDR:

const cldr = Globalize.cldr;

cldr.supplemental("calendarData/chinese");

Локализация числовых значений

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

const numberFormatter = globalize.numberFormatter();

numberFormatter(2026);

В китайской локали числа могут отображаться как:

  • арабские цифры
  • китайские иероглифические числительные (в зависимости от контекста CLDR)

Эры и циклическое летоисчисление

Одной из особенностей китайского календаря является использование циклической системы лет:

  • 10 небесных стволов
  • 12 земных ветвей
  • комбинация формирует 60-летний цикл

CLDR предоставляет данные для отображения этих значений:

cldr.main("dates/calendars/chinese/eras");

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


Ограничения реализации в Globalize

Работа с китайским календарём через Globalize имеет ряд ограничений:

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

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


Совместимость локалей

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

  • zh — упрощённый китайский
  • zh-Hans — упрощённый вариант с региональными отличиями
  • zh-Hant — традиционный китайский

Каждая локаль влияет на:

  • названия месяцев
  • формат чисел
  • порядок элементов даты
  • символику календарных обозначений
Globalize.locale("zh-Hant");

Интеграция с пользовательскими форматами

Globalize позволяет комбинировать календарь с пользовательскими шаблонами:

globalize.dateFormatter({
  skeleton: "yMMMMd",
  calendar: "chinese"
});

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


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

Один и тот же момент времени может быть представлен одновременно в нескольких системах:

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

Globalize обеспечивает согласованное преобразование без изменения исходного значения времени.


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

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

globalize.dateFormatter({
  datetime: "full",
  timeZone: "Asia/Shanghai",
  calendar: "chinese"
});

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