Библиотека js-joda опирается на строгую модель времени,
заимствованную из java.time. Центральной системой является
ISO-8601 календарь, представленный типом LocalDate. Любые
альтернативные календари рассматриваются как надстройки над базовой
временной шкалой, а не как самостоятельные несовместимые системы.
Ключевой принцип: все календарные системы приводятся к единому числу дней с начала эпохи (epoch day), после чего выполняется обратное преобразование в нужную календарную систему.
LocalDate — это ISO-датa без часового пояса:
import { LocalDate } from '@js-joda/core';
const isoDate = LocalDate.of(2026, 5, 25);
Вся конвертация между календарями начинается именно с этого типа.
Для поддержки альтернативных календарей используется
ChronoLocalDate.
Он определяет единый набор операций:
toEpochDay)toLocalDate)Поддержка дополнительных календарных систем реализуется через пакет расширений:
import {
HijrahDate,
JapaneseDate,
MinguoDate,
ThaiBuddhistDate
} from '@js-joda/extra';
Каждый тип представляет собственную календарную систему:
Любая дата в js-joda может быть сведена к числу дней от эпохи:
const iso = LocalDate.of(2026, 5, 25);
const epochDay = iso.toEpochDay();
Это ключевая точка перехода между календарями.
import { LocalDate } from '@js-joda/core';
import { HijrahDate } from '@js-joda/extra';
const iso = LocalDate.of(2026, 5, 25);
const hijrah = HijrahDate.from(iso);
Здесь выполняется:
import { JapaneseDate } from '@js-joda/extra';
const iso = LocalDate.of(2026, 5, 25);
const jp = JapaneseDate.from(iso);
Японский календарь учитывает эры (Reiwa, Heisei и т.д.), но хранит ту же абсолютную дату.
import { ThaiBuddhistDate } from '@js-joda/extra';
const iso = LocalDate.of(2026, 5, 25);
const thai = ThaiBuddhistDate.from(iso);
import { MinguoDate } from '@js-joda/extra';
const iso = LocalDate.of(2026, 5, 25);
const minguo = MinguoDate.from(iso);
Любой ChronoLocalDate можно привести к
LocalDate:
const isoBack = hijrah.toLocalDate();
или аналогично:
const isoFromJapanese = jp.toLocalDate();
Принцип одинаков для всех календарей:
const iso = LocalDate.of(2026, 5, 25);
const chrono = HijrahDate.from(iso);
const backToIso = chrono.toLocalDate();
Это демонстрирует, что альтернативные календари не разрывают модель данных, а лишь изменяют интерпретацию.
const iso = LocalDate.of(2026, 5, 25);
const epoch = iso.toEpochDay();
Создание календаря из epochDay:
const hijrah = HijrahDate.ofEpochDay(epoch);
const japanese = JapaneseDate.ofEpochDay(epoch);
Эта форма является наиболее стабильной при любых преобразованиях.
Несмотря на различие систем, сравнение всегда происходит через абсолютную шкалу.
const a = HijrahDate.from(LocalDate.of(2026, 5, 25));
const b = JapaneseDate.from(LocalDate.of(2026, 5, 25));
const same = a.toEpochDay() === b.toEpochDay();
Результат всегда определяется не календарём, а моментом на временной оси.
Распространённый паттерн:
const hijrah = HijrahDate.from(LocalDate.of(2026, 5, 25));
const iso = hijrah.toLocalDate();
const japanese = JapaneseDate.from(iso);
Такой подход гарантирует:
JapaneseDate содержит дополнительный уровень — эру:
import { JapaneseDate } from '@js-joda/extra';
const iso = LocalDate.of(2019, 5, 1);
const jp = JapaneseDate.from(iso);
При обратной конвертации:
const back = jp.toLocalDate();
Эра не влияет на epochDay, но влияет на представление года.
Некоторые календарные системы имеют особенности:
Однако js-joda нормализует всё через epochDay, исключая неоднозначность.
Типичный сценарий миграции данных:
const isoDates = [
LocalDate.of(2026, 1, 1),
LocalDate.of(2026, 2, 1),
LocalDate.of(2026, 3, 1)
];
const hijrahDates = isoDates.map(HijrahDate.from);
Обратное преобразование:
const backToIso = hijrahDates.map(d => d.toLocalDate());
При хранении данных рекомендуется использовать ISO как универсальный формат:
const iso = LocalDate.of(2026, 5, 25);
const serialized = iso.toString(); // "2026-05-25"
Восстановление:
const restored = LocalDate.parse(serialized);
А затем конвертация:
const hijrah = HijrahDate.from(restored);
Все календарные системы в js-joda подчиняются следующим правилам:
Эти принципы обеспечивают детерминированность конвертаций независимо от календаря.
ChronoLocalDate (любая система)
↓
epochDay
↓
LocalDate (ISO)
↓
ChronoLocalDate (другая система)
Такая архитектура делает конвертацию между календарями симметричной и воспроизводимой во всех поддерживаемых типах js-joda.