Работа с референсными датами

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

  • текущий момент времени
  • дата создания сущности (заказа, пользователя, события)
  • фиксированная бизнес-дата (начало периода подписки, дедлайн)
  • произвольная контрольная точка для аналитики

В библиотеке Day.js любая операция сравнения, смещения или вычисления разницы опирается на два объекта даты: исходный и референсный. Это позволяет строить предсказуемую временную логику без ручной работы с Date.


Создание базовой точки отсчёта

Day.js создаёт неизменяемые объекты даты, которые удобно использовать как референс.

import dayjs from 'dayjs';

const reference = dayjs('2026-01-01T00:00:00Z');
const current = dayjs();

Референсная дата может быть:

  • строкой ISO
  • объектом Date
  • timestamp
  • результатом другого вызова Day.js
const fromTimestamp = dayjs(1700000000000);
const fromDate = dayjs(new Date());

Ключевая особенность: объект Day.js не изменяется, поэтому любая операция возвращает новый экземпляр.


Сравнение дат относительно референса

Проверка порядка

Методы isBefore, isAfter и isSame позволяют определить положение даты относительно базовой точки.

const ref = dayjs('2026-01-01');
const target = dayjs('2026-02-01');

target.isAfter(ref);  // true
target.isBefore(ref); // false

Можно уточнять единицы измерения:

target.isAfter(ref, 'month');
target.isSame(ref, 'year');

Поддерживаемые единицы включают year, month, day, hour, minute, second.


Вычисление разницы относительно референса

Метод diff является центральным инструментом работы с референсными датами.

const ref = dayjs('2026-01-01');
const target = dayjs('2026-01-10');

target.diff(ref, 'day'); // 9

Разница может вычисляться в различных единицах:

target.diff(ref, 'hour');
target.diff(ref, 'month');
target.diff(ref, 'year');

Особенность поведения:

  • результат всегда округляется вниз
  • направление зависит от порядка аргументов
ref.diff(target, 'day'); // -9

Референс в обратных вычислениях

Часто требуется не просто разница, а обратное выражение — «сколько времени осталось до события относительно текущего момента».

const deadline = dayjs('2026-12-31');
const now = dayjs();

const daysLeft = deadline.diff(now, 'day');

Такой подход используется в:

  • системах дедлайнов
  • подписках
  • таймерах
  • SLA-метриках

Нормализация референса через startOf и endOf

Референсная дата часто приводится к границе временного интервала.

const ref = dayjs('2026-05-22T14:35:00');

ref.startOf('day');  // 2026-05-22 00:00:00
ref.endOf('day');    // 2026-05-22 23:59:59.999

Это особенно важно при сравнении диапазонов:

const start = dayjs('2026-05-01');
const end = dayjs('2026-05-31');

const target = dayjs('2026-05-22');

target.isBetween(start.startOf('day'), end.endOf('day'));

Клонирование референса и сохранение состояния

Каждая операция Day.js возвращает новый объект, но при работе с цепочками важно явно фиксировать базовую точку:

const base = dayjs('2026-01-01');

const modified = base.add(10, 'day');
const comparison = base.diff(modified, 'day');

Референс сохраняется неизменным, что устраняет необходимость в ручном клонировании, но логически важно различать:

  • базовую дату
  • производные значения

Работа с UTC как референсной моделью

В распределённых системах референсная дата часто должна быть независимой от локального часового пояса.

import utc from 'dayjs/plugin/utc';
dayjs.extend(utc);

const refUtc = dayjs.utc('2026-01-01T00:00:00Z');
const local = dayjs();

UTC используется как стабильный эталон для:

  • логирования событий
  • синхронизации сервисов
  • расчётов между регионами

Относительные вычисления от референса

Day.js поддерживает построение относительных интервалов через вычисления между базовой и целевой датой.

const base = dayjs('2026-01-01');
const event = dayjs('2026-01-15');

const diffDays = event.diff(base, 'day');
const diffHours = event.diff(base, 'hour');

Такой подход используется для:

  • метрик времени выполнения
  • аналитики пользовательской активности
  • построения временных шкал

Бизнес-паттерны использования референсных дат

Периоды подписки

const start = dayjs('2026-01-01');
const end = start.add(30, 'day');

const now = dayjs();

const isActive = now.isBefore(end) && now.isAfter(start);

Возраст объекта

const createdAt = dayjs('2024-03-10');
const now = dayjs();

const ageInDays = now.diff(createdAt, 'day');

Проверка истечения срока

const expiresAt = dayjs('2026-06-01');

const isExpired = dayjs().isAfter(expiresAt);

Границы периода как референсные якоря

Референсная дата часто используется для нормализации периода.

const ref = dayjs('2026-05-22T18:45:00');

const monthStart = ref.startOf('month');
const monthEnd = ref.endOf('month');

Это позволяет формировать стабильные диапазоны независимо от исходного времени.


Сравнение нескольких дат относительно одной базы

Один референс может использоваться для множества сравнений:

const base = dayjs('2026-01-01');

const dates = [
  dayjs('2026-01-02'),
  dayjs('2026-02-10'),
  dayjs('2025-12-31')
];

const result = dates.map(d => ({
  diff: d.diff(base, 'day'),
  after: d.isAfter(base)
}));

Особенности точности и округления при diff

Метод diff не возвращает дробные значения:

const a = dayjs('2026-01-01 00:00:00');
const b = dayjs('2026-01-01 23:59:59');

b.diff(a, 'day'); // 0

Для точных вычислений используется меньшая единица:

b.diff(a, 'hour'); // 23

Частые ошибки при работе с референсами

Игнорирование единиц измерения

target.diff(ref); // миллисекунды по умолчанию

Сравнение без нормализации

dayjs('2026-01-01T23:59').isSame(dayjs('2026-01-01'), 'day'); // true

Без указания единицы результат может быть неожиданным.

Путаница локального времени и UTC

dayjs('2026-01-01Z'); // UTC
dayjs('2026-01-01');  // локальное время

Использование референсной даты как центрального узла вычислений

В сложных системах референсная дата становится точкой, вокруг которой строится вся временная логика:

  • фильтрация данных по периоду
  • вычисление задержек
  • контроль жизненного цикла объектов
  • построение временных окон анализа

Day.js обеспечивает компактный и предсказуемый набор операций для работы с такими сценариями, сохраняя неизменяемость объектов и явную семантику каждого преобразования.