Порядок даты

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

В библиотеке 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");

a < b; // true
a > b; // false

Сравнение работает благодаря внутренней реализации valueOf(), возвращающей числовое представление времени.


Нормализация времени и влияние временных зон

Один и тот же момент может быть записан в разных временных зонах, но его порядок относительно других дат остаётся неизменным. Luxon нормализует сравнение через UTC-представление.

const utc = DateTime.fromISO("2026-01-01T10:00:00Z");
const local = DateTime.fromISO("2026-01-01T13:00:00+03:00");

utc.equals(local); // true

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

Особенности:

  • временная зона влияет только на отображение;
  • порядок определяется моментом времени;
  • конвертация в UTC происходит автоматически при сравнении.

Числовая основа сравнения DateTime

Любой объект DateTime можно привести к числовому значению:

const dt = DateTime.now();

dt.toMillis(); // число миллисекунд
dt.valueOf();  // то же самое

Именно это значение используется при сортировке и сравнении:

const a = DateTime.fromISO("2026-01-01");
const b = DateTime.fromISO("2025-12-31");

a.valueOf() > b.valueOf(); // true

Это делает возможным прямое использование операторов <, >, <=, >= без дополнительных преобразований.


Лексикографический порядок ISO и его ограничения

ISO-строки часто воспринимаются как уже упорядоченные, однако это верно только при одинаковой временной зоне или её отсутствии.

"2026-01-01T10:00" > "2025-12-31T23:59"; // true

Однако при наличии зон:

"2026-01-01T00:00+02:00" и "2025-12-31T23:00Z"

строковое сравнение перестаёт отражать реальный порядок событий.

Luxon устраняет эту проблему, переводя все значения к единой временной шкале.


Сортировка массивов DateTime

При работе с наборами дат основная операция — сортировка по возрастанию или убыванию времени.

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

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

Выражение a - b корректно работает, поскольку DateTime приводится к числу через valueOf().

Альтернативная форма:

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

Особенности сортировки:

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

Методы проверки порядка

Luxon предоставляет набор методов для явного сравнения:

  • equals(other) — проверка идентичного момента времени;
  • startOf(unit) и endOf(unit) — приведение к границам периода;
  • diff(other) — вычисление разницы между датами.
const a = DateTime.fromISO("2026-01-01T00:00");
const b = DateTime.fromISO("2026-01-02T00:00");

a < b; // true
a.diff(b).toObject(); // отрицательная разница

Метод diff не используется для сортировки напрямую, но полезен для анализа расстояния между моментами.


Пограничные случаи и невалидные значения

Если объект DateTime невалиден, любые операции сравнения теряют смысл:

const invalid = DateTime.fromISO("не дата");

invalid.isValid; // false

В таком состоянии:

  • valueOf() возвращает NaN;
  • сравнение с другими датами даёт непредсказуемый результат;
  • сортировка может нарушаться.

Поэтому порядок дат корректен только при гарантированно валидных объектах.


Учет календарных преобразований

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

const dt1 = DateTime.fromObject({ year: 2026, month: 1, day: 1 });
const dt2 = dt1.plus({ days: 1 });

Несмотря на возможные различия в календарном представлении, внутреннее значение времени остаётся непрерывным и линейным.


Сравнение через UNIX-время

Иногда используется явное сравнение через Unix-время:

const a = DateTime.now().toUnixInteger();
const b = DateTime.now().plus({ minutes: 10 }).toUnixInteger();

a < b;

Unix-представление удобно для:

  • хранения в базах данных;
  • передачи между системами;
  • минимизации зависимости от временных зон.

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

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

const a = DateTime.fromMillis(1700000000000);
const b = DateTime.fromMillis(1700000000000);

a.equals(b); // true
a < b; // false
a > b; // false

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