Нативный объект Date в JavaScript представляет собой
изменяемую (mutable) сущность, внутри которой хранится количество
миллисекунд с эпохи Unix. Любая операция над датой либо изменяет
существующий объект (в случае set* методов), либо
возвращает новое значение через косвенные преобразования.
js-joda реализует противоположный подход: все временные объекты являются неизменяемыми. Любая операция (прибавление дней, смена часового пояса, форматирование) возвращает новый объект, не модифицируя исходный.
const d1 = new Date();
d1.setDate(d1.getDate() + 1); // мутирует исходный объект
const { LocalDate } = require('@js-joda/core');
const d2 = LocalDate.now().plusDays(1); // возвращает новый объект
Ключевое различие:
Date — изменяемое состояниеЭто напрямую влияет на предсказуемость кода, особенно в асинхронных сценариях и при передаче объектов между слоями приложения.
Нативный Date объединяет в себе сразу несколько
концепций:
Такое смешение приводит к неоднозначности при вычислениях.
const d = new Date('2024-03-10T00:00:00');
d.getDate(); // зависит от локальной таймзоны
d.getUTCDate(); // другое значение
js-joda разделяет эти концепции на разные типы:
Instant — абсолютный момент времениLocalDateTime — дата и время без таймзоныZonedDateTime — дата и время с таймзонойLocalDate — только датаLocalTime — только времяТакое разделение устраняет неоднозначность:
const { LocalDate, ZonedDateTime, ZoneId } = require('@js-joda/core');
const date = LocalDate.parse('2024-03-10');
const zoned = ZonedDateTime.now(ZoneId.of('Europe/Berlin'));
Нативные методы Date допускают ряд неочевидных эффектов
при арифметике:
const d = new Date(2024, 0, 31);
d.setMonth(d.getMonth() + 1);
// результат может быть 1 марта вместо 31 февраля
Причина — внутренняя нормализация календаря, зависящая от реализации.
js-joda использует календарную модель ISO-8601 и строгое поведение:
const { LocalDate } = require('@js-joda/core');
const d = LocalDate.of(2024, 1, 31);
const result = d.plusMonths(1); // 2024-02-29 (корректная календарная логика)
Ключевой эффект:
Date скрыто корректирует некорректные датыDate работает в тесной связке с системным часовым
поясом, что приводит к зависимости от окружения выполнения.
const d = new Date('2024-03-31T02:30:00');
// может быть "невалидным" временем из-за DST
js-joda явно моделирует зоны:
const { ZonedDateTime, ZoneId } = require('@js-joda/core');
const zdt = ZonedDateTime.of(
2024, 3, 31, 2, 30, 0, 0,
ZoneId.of('Europe/Moscow')
);
Преимущества подхода:
Нативный Date требует комбинации методов:
const d = new Date();
d.setFullYear(2025);
d.setMonth(5);
d.setDate(10);
js-joda использует цепочки иммутабельных операций:
const { LocalDate } = require('@js-joda/core');
const d = LocalDate.now()
.withYear(2025)
.withMonth(6)
.withDayOfMonth(10);
Отличие проявляется в следующих аспектах:
Нативный парсинг Date зависит от реализации движка и
часто ведёт к неоднозначным результатам:
new Date('2024-01-01'); // интерпретация зависит от окружения
js-joda использует строгие ISO-форматы и явные парсеры:
const { LocalDate } = require('@js-joda/core');
const d = LocalDate.parse('2024-01-01');
Форматирование также отделено:
const { DateTimeFormatter } = require('@js-joda/core');
const formatter = DateTimeFormatter.ofPattern('dd-MM-yyyy');
d.format(formatter);
Ключевое различие:
Date — нестрогий и контекстный парсингОперации над Date часто приводят к скрытым
корректировкам:
const d = new Date(2024, 2, 31);
d.setDate(d.getDate() + 1);
Результат зависит от локальной системы и может варьироваться.
js-joda делает правила явными:
const { LocalDate } = require('@js-joda/core');
LocalDate.of(2024, 3, 31).plusDays(1);
Поведение строго определено ISO-стандартом.
Date не имеет встроенной модели интервалов. Все
вычисления выполняются вручную:
const diff = (d1, d2) => d2 - d1;
js-joda предоставляет специализированные типы:
const { Duration, Period } = require('@js-joda/core');
const duration = Duration.between(startInstant, endInstant);
const period = Period.between(startDate, endDate);
Разделение концепций:
Duration — машинное время (секунды, миллисекунды)Period — календарные единицы (дни, месяцы, годы)Основная проблема Date — скрытые зависимости:
js-joda минимизирует неопределённость за счёт:
Date оптимизирован на уровне движка JavaScript и обычно
имеет меньшие накладные расходы на простые операции.
js-joda создаёт новые объекты при каждой операции, что:
В большинстве прикладных сценариев (бизнес-логика, расписания, финансы) стоимость дополнительных объектов компенсируется снижением ошибок и упрощением поддержки.
Date представляет универсальный контейнер времени без
разделения смыслов.
js-joda строит доменную модель времени, где каждое понятие выделено:
Такое разделение устраняет необходимость ручного контроля контекста и снижает риск ошибок при преобразованиях между уровнями представления времени.