IsoChronology как стандарт

В библиотеке js-joda хронология определяет календарную систему, по правилам которой интерпретируются даты, месяцы, годы и эпохи. IsoChronology представляет стандартную международную календарную систему ISO-8601 — именно она используется большинством приложений, баз данных, API и интернет-протоколов.

ISO-хронология основана на:

  • григорианском календаре;
  • годах, месяцах и днях современного формата;
  • международном стандарте ISO-8601;
  • проолептическом григорианском исчислении.

Практически все основные классы js-joda работают именно через IsoChronology:

  • LocalDate
  • LocalDateTime
  • ZonedDateTime
  • OffsetDateTime
  • Year
  • MonthDay
  • Period

Подключение библиотеки

const { IsoChronology } = require('@js-joda/core')

ESM-вариант:

import { IsoChronology } from '@js-joda/core'

Архитектура хронологий в js-joda

Внутри библиотеки существует абстрактная система календарей:

Компонент Назначение
Chronology Базовый интерфейс календарной системы
IsoChronology Реализация ISO-8601
ChronoLocalDate Абстрактная дата в любой хронологии
Era Эпоха календаря
ChronoField Поля даты и времени

IsoChronology является реализацией Chronology.


Почему ISO-хронология используется по умолчанию

ISO-8601 считается мировым стандартом хранения и передачи дат.

Причины использования:

  • совместимость между системами;
  • единый формат сериализации;
  • отсутствие неоднозначностей;
  • поддержка временных зон;
  • соответствие RFC и международным стандартам.

Например:

2026-05-25

Интерпретируется одинаково:

  • в JavaScript;
  • в Java;
  • в PostgreSQL;
  • в REST API;
  • в JSON;
  • в большинстве СУБД.

Получение экземпляра IsoChronology

IsoChronology реализован как singleton.

const { IsoChronology } = require('@js-joda/core')

const iso = IsoChronology.INSTANCE

console.log(iso)

Singleton означает:

  • экземпляр создаётся один раз;
  • используется глобально;
  • не требует конструктора.

Проверка идентификатора хронологии

console.log(IsoChronology.INSTANCE.id())

Результат:

ISO

Проверка типа календаря

console.log(IsoChronology.INSTANCE.calendarType())

Результат:

iso8601

Это значение соответствует международному стандарту Unicode CLDR.


Создание даты через IsoChronology

Метод date()

const { IsoChronology } = require('@js-joda/core')

const date = IsoChronology.INSTANCE.date(2026, 8, 15)

console.log(date.toString())

Результат:

2026-08-15

Создание даты из эпохи

ISO-хронология поддерживает эпохи:

  • BCE
  • CE

Использование prolepticYear()

const { IsoChronology, IsoEra } = require('@js-joda/core')

const year = IsoChronology.INSTANCE.prolepticYear(
    IsoEra.CE,
    2026
)

console.log(year)

Результат:

2026

Работа с BCE

const { IsoChronology, IsoEra } = require('@js-joda/core')

const year = IsoChronology.INSTANCE.prolepticYear(
    IsoEra.BCE,
    1
)

console.log(year)

Результат:

0

В ISO-хронологии:

Исторический год ISO
1 BCE 0
2 BCE -1
3 BCE -2

Такое представление называется проолептическим исчислением.


Проверка високосного года

Метод isLeapYear()

const { IsoChronology } = require('@js-joda/core')

console.log(
    IsoChronology.INSTANCE.isLeapYear(2024)
)

Результат:

true

Правила високосного года

ISO использует григорианские правила:

Год високосный если:

  1. делится на 4;
  2. не делится на 100;

или:

  1. делится на 400.

Примеры проверки

console.log(
    IsoChronology.INSTANCE.isLeapYear(2000)
)
true

console.log(
    IsoChronology.INSTANCE.isLeapYear(1900)
)
false

console.log(
    IsoChronology.INSTANCE.isLeapYear(2023)
)
false

Создание даты из day-of-year

Метод dateYearDay()

const { IsoChronology } = require('@js-joda/core')

const date = IsoChronology.INSTANCE.dateYearDay(
    2026,
    120
)

console.log(date.toString())

Результат:

2026-04-30

Когда удобно использовать day-of-year

Такой формат полезен:

  • в финансовых системах;
  • в астрономии;
  • в научных расчётах;
  • в календарных индексах;
  • в GPS и телеметрии.

Создание даты из epoch day

Метод dateEpochDay()

epoch day — количество дней от 1970-01-01.

const { IsoChronology } = require('@js-joda/core')

const date = IsoChronology.INSTANCE.dateEpochDay(0)

console.log(date.toString())

Результат:

1970-01-01

Отрицательные epoch day

const date = IsoChronology.INSTANCE.dateEpochDay(-1)

console.log(date.toString())

Результат:

1969-12-31

Преобразование TemporalAccessor

IsoChronology умеет преобразовывать объекты времени.

Метод date()

const {
    IsoChronology,
    LocalDateTime
} = require('@js-joda/core')

const dateTime = LocalDateTime.now()

const date = IsoChronology.INSTANCE.date(dateTime)

console.log(date.toString())

Получение текущей даты

Метод dateNow()

const { IsoChronology } = require('@js-joda/core')

const today = IsoChronology.INSTANCE.dateNow()

console.log(today.toString())

Работа с часовыми поясами

const {
    IsoChronology,
    ZoneId
} = require('@js-joda/core')

const tokyoDate =
    IsoChronology.INSTANCE.dateNow(
        ZoneId.of('Asia/Tokyo')
    )

console.log(tokyoDate.toString())

Создание LocalDateTime

Метод localDateTime()

const {
    IsoChronology,
    Instant,
    ZoneOffset
} = require('@js-joda/core')

const instant = Instant.now()

const dateTime =
    IsoChronology.INSTANCE.localDateTime(
        instant,
        ZoneOffset.UTC
    )

console.log(dateTime.toString())

Создание ZonedDateTime

Метод zonedDateTime()

const {
    IsoChronology,
    Instant,
    ZoneId
} = require('@js-joda/core')

const zoned =
    IsoChronology.INSTANCE.zonedDateTime(
        Instant.now(),
        ZoneId.of('Europe/Berlin')
    )

console.log(zoned.toString())

Преобразование Instant

IsoChronology активно взаимодействует с:

Тип Назначение
Instant Точка времени UTC
ZoneId Идентификатор зоны
ZoneOffset Смещение UTC
Clock Источник времени

Работа с эпохами

Метод eraOf()

const { IsoChronology } = require('@js-joda/core')

const era = IsoChronology.INSTANCE.eraOf(1)

console.log(era.toString())

Результат:

CE

Поддерживаемые эпохи

Значение Эпоха
0 BCE
1 CE

Получение списка эпох

const eras = IsoChronology.INSTANCE.eras()

console.log(eras)

Проверка корректности даты

IsoChronology валидирует даты автоматически.

Некорректная дата

IsoChronology.INSTANCE.date(2025, 2, 30)

Результат:

DateTimeException

Проверка диапазонов

Проверяются:

  • дни месяца;
  • номер месяца;
  • високосные даты;
  • day-of-year;
  • epoch day;
  • эпохи.

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

ISO-хронология распространяет современные правила григорианского календаря на всё прошлое.

Это означает:

  • исторические реформы игнорируются;
  • отсутствует переход с юлианского календаря;
  • расчёты становятся математически непрерывными.

Историческая особенность

В реальной истории:

  • после 1582-10-04
  • наступило 1582-10-15

В IsoChronology такого разрыва нет.

const date = IsoChronology.INSTANCE.date(
    1582,
    10,
    10
)

console.log(date.toString())

Результат:

1582-10-10

Сравнение с native Date

Native Date

const date = new Date()

Проблемы:

  • mutable API;
  • сложная работа с timezone;
  • неявные преобразования;
  • ошибки локали;
  • нестабильный парсинг.

IsoChronology + js-joda

Преимущества:

  • immutable объекты;
  • строгая ISO-модель;
  • безопасная арифметика;
  • предсказуемый API;
  • отсутствие скрытых timezone-конверсий.

Связь с LocalDate

LocalDate фактически использует IsoChronology.

const { LocalDate } = require('@js-joda/core')

const date = LocalDate.now()

console.log(
    date.chronology().id()
)

Результат:

ISO

Проверка хронологии объекта

const { LocalDate } = require('@js-joda/core')

const date = LocalDate.now()

console.log(
    date.chronology() ===
    IsoChronology.INSTANCE
)

Результат:

true

Внутреннее значение IsoChronology

IsoChronology играет роль фундаментального календарного движка библиотеки.

Через него реализуются:

  • вычисления дат;
  • переходы между месяцами;
  • високосная логика;
  • day-of-year;
  • преобразования epoch;
  • работа эпох;
  • временные преобразования.

Основные методы IsoChronology

Метод Назначение
date() Создание даты
dateNow() Текущая дата
dateEpochDay() Дата из epoch day
dateYearDay() Дата из day-of-year
isLeapYear() Проверка високосного года
prolepticYear() ISO-год
eraOf() Получение эпохи
eras() Список эпох
localDateTime() Создание LocalDateTime
zonedDateTime() Создание ZonedDateTime

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

const {
    IsoChronology
} = require('@js-joda/core')

const iso = IsoChronology.INSTANCE

const year = 2024

if (iso.isLeapYear(year)) {
    console.log('366 days')
} else {
    console.log('365 days')
}

Использование в enterprise-приложениях

ISO-хронология особенно важна в:

  • банковских системах;
  • ERP;
  • CRM;
  • международных API;
  • авиации;
  • логистике;
  • медицинских системах;
  • финансовой аналитике.

Причина — единое и строго стандартизированное поведение дат.


Совместимость с ISO-8601

IsoChronology полностью ориентирован на ISO-8601:

Формат Пример
Дата 2026-05-25
Время 14:30:00
UTC 2026-05-25T14:30:00Z
Offset 2026-05-25T14:30:00+03:00
Zoned 2026-05-25T14:30:00+03:00[Europe/Moscow]

Immutable-модель

Все объекты, создаваемые через IsoChronology, неизменяемы.

const date1 =
    IsoChronology.INSTANCE.date(2026, 1, 1)

const date2 = date1.plusDays(10)

console.log(date1.toString())
console.log(date2.toString())

Результат:

2026-01-01
2026-01-11

Исходный объект не изменяется.


Безопасность вычислений

Immutable-подход предотвращает:

  • случайные мутации;
  • race condition;
  • ошибки многопоточности;
  • скрытые изменения состояния;
  • проблемы кэширования.

Производительность

IsoChronology оптимизирован для:

  • массовых вычислений;
  • сериализации;
  • API;
  • работы с большими объёмами дат;
  • вычислений диапазонов времени.

Singleton-архитектура уменьшает количество создаваемых объектов.


Роль IsoChronology в экосистеме js-joda

Практически вся библиотека строится вокруг ISO-модели времени:

Класс Использование ISO
LocalDate Да
LocalDateTime Да
OffsetDateTime Да
ZonedDateTime Да
Instant Да
Period Да
Duration Частично
YearMonth Да

Когда работать напрямую с IsoChronology

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

  • при создании инфраструктурных библиотек;
  • в фреймворках;
  • при написании ORM;
  • при реализации temporal abstraction;
  • для универсальных календарных API;
  • при работе с Chronology.

В большинстве прикладных задач используется LocalDate и связанные типы, которые уже основаны на IsoChronology.