Сравнение дат

В библиотеке Luxon базовой сущностью для работы с датами является объект DateTime. Он инкапсулирует момент времени, временную зону, календарные параметры и предоставляет набор методов для безопасных преобразований и сравнений.

Сравнение дат в Luxon строится вокруг нескольких уровней: сравнение по точному моменту времени, сравнение по календарным компонентам, а также вычисление относительных различий.


Базовое сравнение по моменту времени

Любой DateTime в конечном счёте может быть приведён к числу миллисекунд с начала Unix-эпохи. Это позволяет выполнять строгое сравнение:

import { DateTime } from "luxon";

const a = DateTime.fromISO("2026-01-01T10:00:00");
const b = DateTime.fromISO("2026-01-01T12:00:00");

const result = a.toMillis() < b.toMillis();

Метод toMillis() возвращает абсолютное значение времени, независимое от календарных представлений. Это наиболее надёжная форма сравнения, если требуется определить порядок событий.

Альтернативой служит приведение к числу через valueOf():

const result = a.valueOf() === b.valueOf();

Оба подхода работают с одинаковой семантикой, поскольку valueOf() возвращает тот же Unix timestamp в миллисекундах.


Методы сравнения isBefore, isAfter, equals

Luxon предоставляет специализированные методы для повышения выразительности кода.

isBefore и isAfter

a.isBefore(b);
a.isAfter(b);

Эти методы выполняют сравнение с учётом временной зоны и точного момента времени.

const a = DateTime.fromISO("2026-05-01T00:00:00+03:00");
const b = DateTime.fromISO("2026-05-01T00:00:00Z");

const result = a.isBefore(b);

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

equals

a.equals(b);

Метод equals проверяет полное совпадение всех значимых полей: момент времени, зона, календарные параметры.

const a = DateTime.fromISO("2026-01-01T10:00:00Z");
const b = DateTime.utc(2026, 1, 1, 10, 0, 0);

const result = a.equals(b);

Даже при совпадении времени результат может быть false, если различается зона или внутреннее представление.


Сравнение с игнорированием временной зоны

В ряде сценариев требуется сравнение только по локальному времени без учёта зоны. Для этого используется нормализация через setZone или приведение к UTC.

const a = DateTime.fromISO("2026-01-01T10:00:00+02:00").toUTC();
const b = DateTime.fromISO("2026-01-01T12:00:00+04:00").toUTC();

const result = a.equals(b);

Обе даты представляют один и тот же момент времени после нормализации.


Сравнение по календарным компонентам

Часто требуется игнорировать точное время и сравнивать только дату.

const a = DateTime.fromISO("2026-01-01T10:00:00");
const b = DateTime.fromISO("2026-01-01T22:00:00");

const sameDay = a.hasSame(b, "day");

Метод hasSame позволяет указать уровень сравнения:

  • year
  • month
  • day
  • hour
  • minute
a.hasSame(b, "month");

Это сравнение основано на календарных значениях, а не на абсолютных миллисекундах.


Сравнение диапазонов дат

Для анализа интервалов используется объект Interval.

import { DateTime, Interval } from "luxon";

const start = DateTime.fromISO("2026-01-01");
const end = DateTime.fromISO("2026-01-10");

const interval = Interval.fromDateTimes(start, end);

const point = DateTime.fromISO("2026-01-05");

const contains = interval.contains(point);

Интервалы позволяют проверять вхождение, пересечение и частичное совпадение.


Лексикографическое сравнение и сортировка

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

const dates = [
  DateTime.fromISO("2026-03-01"),
  DateTime.fromISO("2026-01-01"),
  DateTime.fromISO("2026-02-01")
];

dates.sort((a, b) => a.toMillis() - b.toMillis());

Альтернативный вариант:

dates.sort((a, b) => a - b);

Поскольку DateTime реализует valueOf, объекты корректно приводятся к числам.


Сравнение с учётом округления

Для сценариев группировки времени применяется округление через startOf:

const a = DateTime.fromISO("2026-01-01T10:15:00");
const b = DateTime.fromISO("2026-01-01T18:45:00");

const sameHourBlock = a.startOf("hour").equals(b.startOf("hour"));

Метод startOf обнуляет младшие компоненты времени, позволяя сравнивать даты по дискретным интервалам.


Диапазонные проверки через diff

Метод diff позволяет вычислять разницу между датами:

const a = DateTime.fromISO("2026-01-10");
const b = DateTime.fromISO("2026-01-01");

const diff = a.diff(b, "days").days;

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

const isMoreThanWeekApart = Math.abs(diff) > 7;

Нормализация перед сравнением

Разные форматы входных данных часто требуют унификации:

const normalize = (dt) => dt.setZone("utc").startOf("second");

const a = normalize(DateTime.fromISO("2026-01-01T10:00:00+03:00"));
const b = normalize(DateTime.utc(2026, 1, 1, 7, 0, 0));

const result = a.equals(b);

Нормализация снижает вероятность расхождений из-за миллисекунд, зон и лишних компонентов.


Сравнение «раньше/позже» через числовую шкалу

При построении алгоритмов планирования часто используется явное числовое сравнение:

function compareDates(a, b) {
  return a.toMillis() - b.toMillis();
}

const sorted = dates.sort(compareDates);

Результат:

  • отрицательное значение — первая дата раньше
  • ноль — равенство
  • положительное значение — первая дата позже

Сравнение с учётом частичной точности

Luxon позволяет задавать точность сравнения через комбинацию hasSame и нормализации:

const isSameMinute =
  a.startOf("minute").equals(b.startOf("minute"));

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


Работа с пограничными значениями

Переходы между датами требуют аккуратного сравнения:

const a = DateTime.fromISO("2026-03-01T00:00:00");
const b = DateTime.fromISO("2026-02-28T23:59:59");

const result = a.diff(b, "seconds").seconds;

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


Сравнение в цепочках условий

Комбинирование методов Luxon позволяет формировать сложные условия:

const isValid =
  date.isAfter(start) &&
  date.isBefore(end) &&
  date.hasSame(start, "day");

Такая конструкция объединяет абсолютное и календарное сравнение в одном выражении логики.