Библиотека Js-joda предоставляет реализацию различных календарных
систем, совместимых со спецификацией Java Time API. Помимо стандартного
ISO-календаря доступны исторические и национальные календарные системы,
включая календарь Миньго (Minguo) и тайский буддийский
календарь (ThaiBuddhist).
Поддержка альтернативных календарей реализована через модуль
@js-joda/locale, который включает классы хронологий
(Chronology) и специализированные типы дат.
Для работы с альтернативными календарями требуется установка дополнительных пакетов:
npm install @js-joda/core
npm install @js-joda/locale
Импорт:
const {
LocalDate,
ChronoField
} = require('@js-joda/core');
const {
MinguoChronology,
ThaiBuddhistChronology
} = require('@js-joda/locale');
В Js-joda любая календарная система реализуется через объект
Chronology.
Основные задачи хронологии:
ISO-календарь используется по умолчанию, однако альтернативные календари сохраняют совместимость с базовыми временными API.
Календарь Миньго используется на Тайване и связан с основанием Китайской Республики.
Особенности:
1 соответствует 1912 году ISO;Соответствие годов:
| Minguo | ISO |
|---|---|
| 1 | 1912 |
| 10 | 1921 |
| 100 | 2011 |
| 112 | 2023 |
const chronology = MinguoChronology.INSTANCE;
const date = chronology.date(112, 5, 20);
console.log(date.toString());
Результат:
Minguo ROC 112-05-20
Здесь:
ROC — Republic of China;112 — год календаря Миньго;05 — месяц;20 — день.const isoDate = LocalDate.of(2023, 5, 20);
const minguoDate = MinguoChronology.INSTANCE.date(isoDate);
console.log(minguoDate.toString());
Результат:
Minguo ROC 112-05-20
const date = MinguoChronology.INSTANCE.date(112, 8, 15);
console.log(date.year());
Результат:
112
console.log(date.monthValue());
console.log(date.dayOfMonth());
Результат:
8
15
Тип ChronoField позволяет получать универсальные
значения независимо от календарной системы.
const year = date.get(ChronoField.YEAR);
console.log(year);
const era = date.get(ChronoField.ERA);
console.log(era);
В календаре Миньго:
1 — ROC;0 — BEFORE_ROC.const oldDate = MinguoChronology.INSTANCE.date(-5, 3, 10);
console.log(oldDate.toString());
Результат:
Minguo BEFORE_ROC 6-03-10
Отрицательные годы автоматически переводятся в эпоху
BEFORE_ROC.
if (oldDate.era().toString() === 'BEFORE_ROC') {
console.log('Дата до основания республики');
}
Все стандартные операции доступны и для альтернативных календарей.
const date = MinguoChronology.INSTANCE.date(112, 1, 1);
const next = date.plusYears(5);
console.log(next.toString());
Результат:
Minguo ROC 117-01-01
const result = date.plusMonths(8);
console.log(result.toString());
const result = date.minusDays(30);
console.log(result.toString());
const d1 = MinguoChronology.INSTANCE.date(112, 5, 1);
const d2 = MinguoChronology.INSTANCE.date(112, 5, 1);
console.log(d1.equals(d2));
const d1 = MinguoChronology.INSTANCE.date(110, 1, 1);
const d2 = MinguoChronology.INSTANCE.date(112, 1, 1);
console.log(d1.isBefore(d2));
console.log(d2.isAfter(d1));
const minguo = MinguoChronology.INSTANCE.date(112, 5, 20);
const iso = LocalDate.from(minguo);
console.log(iso.toString());
Результат:
2023-05-20
Тайский буддийский календарь широко используется в Таиланде.
Главная особенность:
543.Примеры:
| Thai Buddhist | ISO |
|---|---|
| 2566 | 2023 |
| 2567 | 2024 |
| 2500 | 1957 |
Месяцы и дни совпадают с григорианским календарём.
const thai = ThaiBuddhistChronology.INSTANCE;
const date = thai.date(2566, 7, 15);
console.log(date.toString());
Результат:
ThaiBuddhist BE 2566-07-15
const isoDate = LocalDate.of(2023, 7, 15);
const thaiDate =
ThaiBuddhistChronology.INSTANCE.date(isoDate);
console.log(thaiDate.toString());
В тайском календаре используются:
BE — Buddhist Era;BEFORE_BE.const ancient =
ThaiBuddhistChronology.INSTANCE.date(-10, 1, 1);
console.log(ancient.toString());
console.log(date.year());
console.log(date.dayOfYear());
console.log(date.dayOfWeek().toString());
const thaiDate =
ThaiBuddhistChronology.INSTANCE.date(2566, 1, 1);
const iso = LocalDate.from(thaiDate);
console.log(iso.toString());
Результат:
2023-01-01
Напрямую календари не конвертируются. Используется ISO-представление как промежуточный формат.
const minguo =
MinguoChronology.INSTANCE.date(112, 5, 20);
const iso =
LocalDate.from(minguo);
const thai =
ThaiBuddhistChronology.INSTANCE.date(iso);
console.log(thai.toString());
Результат:
ThaiBuddhist BE 2566-05-20
Альтернативные календари поддерживают интерфейс
TemporalAccessor.
const thai =
ThaiBuddhistChronology.INSTANCE.date(2566, 8, 12);
console.log(
thai.getLong(ChronoField.YEAR)
);
const leap =
MinguoChronology.INSTANCE.isLeapYear(112);
console.log(leap);
const leap =
ThaiBuddhistChronology.INSTANCE.isLeapYear(2567);
console.log(leap);
Поскольку оба календаря основаны на ISO-системе, правила високосных лет совпадают с григорианским календарём.
const start =
ThaiBuddhistChronology.INSTANCE.date(2565, 1, 1);
const end =
ThaiBuddhistChronology.INSTANCE.date(2566, 1, 1);
const days =
end.toEpochDay() - start.toEpochDay();
console.log(days);
Внутренне все альтернативные календари используют epoch day — количество дней от UNIX-эпохи.
const thai =
ThaiBuddhistChronology.INSTANCE.date(2566, 6, 1);
console.log(thai.toEpochDay());
Это обеспечивает:
Для форматирования используются стандартные механизмы Js-joda.
const {
DateTimeFormatter
} = require('@js-joda/core');
const thai =
ThaiBuddhistChronology.INSTANCE.date(2566, 5, 10);
const formatter =
DateTimeFormatter.ofPattern('yyyy-MM-dd');
console.log(
formatter.format(thai)
);
Календарь Миньго применяется:
Используется:
Некоторые внешние инструменты работают только с ISO-датами.
В таких случаях используется преобразование:
const iso = LocalDate.from(customDate);
JSON-сериализация часто теряет информацию о календарной системе.
Пример:
JSON.stringify(date.toString());
После десериализации требуется повторное создание объекта через соответствующую chronology.
function createTaiwanDocumentDate() {
return MinguoChronology.INSTANCE.dateNow();
}
const documentDate =
createTaiwanDocumentDate();
console.log(documentDate.toString());
function normalizeDate(date) {
return LocalDate.from(date);
}
const thai =
ThaiBuddhistChronology.INSTANCE.date(2566, 3, 15);
const normalized =
normalizeDate(thai);
console.log(normalized.toString());
Все календарные системы Js-joda строятся вокруг общей модели:
ChronologyChronoLocalDateEraChronoFieldЭто позволяет:
| Характеристика | ISO | Minguo | ThaiBuddhist |
|---|---|---|---|
| Основа | Григорианский | Григорианский | Григорианский |
| Смещение лет | 0 | -1911 | +543 |
| Эпохи | BCE/CE | BEFORE_ROC/ROC | BEFORE_BE/BE |
| Месяцы | Совпадают | Совпадают | Совпадают |
| Дни | Совпадают | Совпадают | Совпадают |
Для баз данных рекомендуется:
Во внешних API желательно передавать:
LocalDate
а локализованное представление строить только на клиентской стороне.
Наиболее надёжный подход:
Это снижает вероятность ошибок при интеграции с внешними сервисами и базами данных.