Работа с прошлым и будущим

Модель времени: неизменяемые объекты и цепочки преобразований

Day.js работает по принципу immutable-объектов: каждое преобразование даты возвращает новый экземпляр, не изменяя исходный.

Это критически важно при работе с прошлым и будущим, так как позволяет строить цепочки вычислений без побочных эффектов.

import dayjs from 'dayjs';

const now = dayjs();
const later = now.add(2, 'day');

console.log(now.format());
console.log(later.format());

now остаётся неизменным, а результат смещения хранится отдельно.


Смещение во времени: add и subtract

Основной механизм работы с будущим и прошлым — методы add и subtract.

Добавление времени (будущее)

dayjs().add(10, 'minute');
dayjs().add(3, 'hour');
dayjs().add(1, 'day');
dayjs().add(2, 'week');
dayjs().add(1, 'month');
dayjs().add(5, 'year');

Метод принимает:

  • число
  • единицу измерения времени

Поддерживаемые единицы:

  • millisecond
  • second
  • minute
  • hour
  • day
  • week
  • month
  • year

Вычитание времени (прошлое)

dayjs().subtract(15, 'minute');
dayjs().subtract(7, 'day');
dayjs().subtract(1, 'month');

Математически subtract(x, unit) эквивалентен add(-x, unit).


Работа с календарными границами: startOf и endOf

При анализе прошлого и будущего часто требуется нормализация до начала или конца временного интервала.

Начало периода

dayjs().startOf('day');
dayjs().startOf('month');
dayjs().startOf('year');

Пример:

const start = dayjs().startOf('day');
console.log(start.format());

Результат: текущая дата с временем 00:00:00.000.

Конец периода

dayjs().endOf('day');
dayjs().endOf('month');
dayjs().endOf('year');

Пример:

const end = dayjs().endOf('month');
console.log(end.format());

Результат: последний момент месяца 23:59:59.999.


Сравнение дат: прошлое, настоящее, будущее

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

  • isBefore
  • isAfter
  • isSame

Проверка на прошлое

dayjs('2024-01-01').isBefore(dayjs());

Проверка на будущее

dayjs('2030-01-01').isAfter(dayjs());

Сравнение с точностью

dayjs('2024-01-01').isSame('2024-01-01', 'day');
dayjs().isSame(dayjs(), 'second');

Точность сравнения задаётся вторым аргументом:

  • year
  • month
  • day
  • hour
  • minute
  • second

Разница между датами: diff

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

const a = dayjs('2024-01-01');
const b = dayjs('2024-01-10');

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

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

b.diff(a, 'hour');
b.diff(a, 'month');
b.diff(a, 'year');

Также поддерживается дробный результат:

b.diff(a, 'day', true); // 9.0 или 9.3 в зависимости от данных

Относительное время: выражение прошлого и будущего

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

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

После подключения:

dayjs().from(dayjs().subtract(5, 'minute')); // "5 minutes ago"
dayjs().to(dayjs().add(2, 'hour')); // "in 2 hours"

Также:

dayjs().fromNow(); // относительно текущего момента (прошлое)
dayjs().toNow();   // относительно текущего момента (будущее)

Формирование временных окон

Работа с будущим и прошлым часто сводится к созданию диапазонов.

Последние 7 дней

const start = dayjs().subtract(7, 'day');
const end = dayjs();

const inLastWeek = (date) =>
  dayjs(date).isAfter(start) && dayjs(date).isBefore(end);

Следующие 30 дней

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

const inNextMonth = (date) =>
  dayjs(date).isAfter(start) && dayjs(date).isBefore(end);

Нормализация дат при работе с будущим

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

dayjs('2024-01-31').add(1, 'month');

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

  • январь 31 → февраль 29/28

Такая особенность связана с календарной логикой, а не арифметикой.


Цепочки операций с временем

Day.js позволяет строить последовательные трансформации:

const result = dayjs()
  .add(2, 'day')
  .subtract(3, 'hour')
  .startOf('hour')
  .add(15, 'minute');

console.log(result.format());

Каждый шаг создаёт новый объект, формируя предсказуемую цепочку.


Проверка попадания в прошлое или будущее относительно порога

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

if (dayjs().isAfter(deadline)) {
  // срок в прошлом
}

if (dayjs().isBefore(deadline)) {
  // срок в будущем
}

Вычисление времени до события

Типичный сценарий — расчёт оставшегося времени:

const event = dayjs('2026-06-10');

const daysLeft = event.diff(dayjs(), 'day');
const hoursLeft = event.diff(dayjs(), 'hour');

При этом выбор единицы влияет на точность результата.


Округление при работе с diff и интервалами

diff всегда возвращает усечённое значение при целых единицах:

dayjs('2026-01-01 12:00').diff('2026-01-01 00:00', 'day'); // 0

Для получения более точной оценки используется третий параметр:

dayjs('2026-01-01 12:00').diff('2026-01-01 00:00', 'day', true); // 0.5

Построение временных шкал

Последовательности будущих или прошедших дат формируются через цикл с add/subtract.

const timeline = [];

for (let i = 0; i < 5; i++) {
  timeline.push(dayjs().add(i, 'day'));
}

Результат — массив объектов, представляющих будущие дни.


Использование временных интервалов в логике приложения

Пример фильтрации событий по диапазону:

const events = [
  { date: '2026-05-20' },
  { date: '2026-05-25' },
  { date: '2026-06-01' }
];

const start = dayjs().subtract(3, 'day');
const end = dayjs().add(10, 'day');

const filtered = events.filter(e => {
  const d = dayjs(e.date);
  return d.isAfter(start) && d.isBefore(end);
});

Работа с будущими датами в планировании

Планирование задач часто строится на фиксированных смещениях:

const reminder = dayjs().add(45, 'minute');
const retry = dayjs().add(2, 'hour');
const backup = dayjs().add(1, 'day');

Такие конструкции используются в:

  • очередях задач
  • системах уведомлений
  • планировщиках событий

Корректная работа с относительными смещениями

Сложные сценарии требуют аккуратного порядка операций:

const result = dayjs()
  .startOf('day')
  .add(1, 'day')
  .subtract(1, 'second');

Здесь важно, что каждая операция опирается на результат предыдущей, формируя точное временное окно.


Обработка исторических дат

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

const birth = dayjs('1990-05-15');
const age = dayjs().diff(birth, 'year');

Такой подход обеспечивает стабильность вычислений независимо от текущей даты.