Функция differenceIn и её варианты

Библиотека date-fns предоставляет набор функций семейства differenceIn*, предназначенных для вычисления разницы между двумя датами в различных единицах измерения времени. Все функции принимают два аргумента: дату-«позднее» и дату-«раньше», и возвращают целое число, отражающее количество полных единиц между ними.

Общий принцип работы:

  • результат всегда целочисленный;
  • дробные части отбрасываются, а не округляются;
  • при обратном порядке дат возвращается отрицательное значение;
  • операции выполняются на основе объектов Date.

Базовые функции разницы во времени

differenceInMilliseconds

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

import { differenceInMilliseconds } from 'date-fns';

const result = differenceInMilliseconds(
  new Date('2024-01-02T00:00:00.000Z'),
  new Date('2024-01-01T00:00:00.000Z')
);
// 86400000

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

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

differenceInSeconds

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

import { differenceInSeconds } from 'date-fns';

differenceInSeconds(
  new Date('2024-01-01T00:00:10.500Z'),
  new Date('2024-01-01T00:00:00.000Z')
);
// 10

differenceInMinutes

Возвращает количество полных минут.

import { differenceInMinutes } from 'date-fns';

differenceInMinutes(
  new Date('2024-01-01T00:05:00'),
  new Date('2024-01-01T00:00:30')
);
// 4

Округление вниз происходит после перевода секунд в минуты.


differenceInHours

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

import { differenceInHours } from 'date-fns';

differenceInHours(
  new Date('2024-01-02T03:00:00'),
  new Date('2024-01-01T00:00:00')
);
// 27

differenceInDays

Возвращает количество полных суток между датами.

import { differenceInDays } from 'date-fns';

differenceInDays(
  new Date('2024-01-10'),
  new Date('2024-01-01')
);
// 9

Функция учитывает переходы через сутки, а не календарные границы.


differenceInWeeks

Переводит разницу в недели (7-дневные интервалы).

import { differenceInWeeks } from 'date-fns';

differenceInWeeks(
  new Date('2024-01-15'),
  new Date('2024-01-01')
);
// 2

differenceInMonths

Вычисляет разницу в календарных месяцах без учёта дней внутри месяца.

import { differenceInMonths } from 'date-fns';

differenceInMonths(
  new Date('2024-03-01'),
  new Date('2024-01-31')
);
// 2

Механика основана на смещении месяца и года, а не на количестве дней.


differenceInYears

Возвращает количество полных лет между датами.

import { differenceInYears } from 'date-fns';

differenceInYears(
  new Date('2025-01-01'),
  new Date('2020-01-01')
);
// 5

differenceInQuarters

Квартальная разница (3 месяца на квартал).

import { differenceInQuarters } from 'date-fns';

differenceInQuarters(
  new Date('2024-10-01'),
  new Date('2024-01-01')
);
// 3

Календарные варианты differenceIn

Календарные функции отличаются тем, что игнорируют «внутренние» единицы времени и сравнивают только календарные границы (дни, месяцы, годы).


differenceInCalendarDays

Сравнение по календарным дням без учёта времени суток.

import { differenceInCalendarDays } from 'date-fns';

differenceInCalendarDays(
  new Date('2024-01-02T23:59:59'),
  new Date('2024-01-01T00:00:00')
);
// 1

Даже при почти двух сутках разница считается как 1 календарный день.


differenceInCalendarMonths

Сравнение по календарным месяцам.

import { differenceInCalendarMonths } from 'date-fns';

differenceInCalendarMonths(
  new Date('2024-03-31'),
  new Date('2024-01-01')
);
// 2

Счёт идёт по переходам месяца, а не по количеству дней.


differenceInCalendarYears

Сравнение по годам.

import { differenceInCalendarYears } from 'date-fns';

differenceInCalendarYears(
  new Date('2026-01-01'),
  new Date('2024-12-31')
);
// 2

differenceInCalendarWeeks

Разница по календарным неделям (с учётом начала недели по ISO/локали).

import { differenceInCalendarWeeks } from 'date-fns';

differenceInCalendarWeeks(
  new Date('2024-01-15'),
  new Date('2024-01-01')
);
// 2

differenceInBusinessDays

Отдельная категория — рабочие дни, исключающие выходные.

import { differenceInBusinessDays } from 'date-fns';

differenceInBusinessDays(
  new Date('2024-01-08'),
  new Date('2024-01-01')
);
// 5

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

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

Поведение и общие особенности семейства differenceIn

Порядок аргументов

Первый аргумент — конечная дата, второй — начальная.

differenceInDays(dateA, dateB)

При обратном порядке результат отрицательный.


Отбрасывание дробной части

Все функции работают по принципу усечения:

  • 1.9 дня → 1 день;
  • 59 секунд → 0 минут;
  • 23 часа → 0 дней.

Округление вверх не применяется.


Независимость от часовых поясов

date-fns опирается на объект Date и его локальное/UTC представление, но не вводит собственной системы часовых поясов. Разница вычисляется через timestamp.


Календарные vs абсолютные функции

Различие моделей вычисления:

  • абсолютные (differenceInDays, differenceInHours) — работают через фиксированные интервалы времени;
  • календарные (differenceInCalendarDays, differenceInCalendarMonths) — ориентируются на смену календарных единиц.

Пример расхождения:

differenceInDays(new Date('2024-03-01'), new Date('2024-02-28')) // 2
differenceInCalendarDays(new Date('2024-03-01'), new Date('2024-02-28')) // 2

Но при переходах через летнее время или нестандартные интервалы расхождения становятся заметнее.


Типичные сценарии применения differenceIn

Измерение длительности операций

const start = new Date();
// операция
const end = new Date();

differenceInMilliseconds(end, start);

Контроль SLA и дедлайнов

differenceInHours(deadline, new Date());

Подсчёт возрастов и стажа

differenceInYears(new Date(), birthDate);

Анализ календарных интервалов

differenceInCalendarMonths(endDate, startDate);

Рабочие периоды

differenceInBusinessDays(endDate, startDate);

Поведение при равных датах

Если даты совпадают:

differenceInDays(date, date); // 0

Во всех вариантах результат равен нулю независимо от типа функции.