Поиск минимума и максимума: min, max

Библиотека date-fns предоставляет набор утилит для работы с датами, построенных вокруг неизменяемых структур и функционального подхода. Среди базовых операций особое место занимают вычисление минимального и максимального значения в наборе дат. Для этого используются функции min и max, позволяющие находить самую раннюю и самую позднюю дату соответственно.


Назначение функций min и max

Обе функции решают задачу агрегации дат:

  • min — возвращает наименьшую (самую раннюю) дату из набора
  • max — возвращает наибольшую (самую позднюю) дату из набора

Операции применимы к массивам Date или числовым представлениям времени (timestamp).


Сигнатуры функций

min

min(dates: Date[] | number[]): Date

max

max(dates: Date[] | number[]): Date

Обе функции принимают массив значений времени и возвращают объект Date.


Базовое поведение

При передаче массива дат выполняется сравнение их временных значений (в миллисекундах от начала эпохи Unix).

import { min, max } from 'date-fns';

const dates = [
  new Date(2024, 0, 10),
  new Date(2023, 5, 20),
  new Date(2025, 2, 1),
];

const earliest = min(dates);
const latest = max(dates);

console.log(earliest); // 2023-06-20T...
console.log(latest);   // 2025-03-01T...

Обработка числовых значений времени

Вместо объектов Date допускается использование timestamp:

import { min, max } from 'date-fns';

const times = [
  Date.parse('2024-01-01'),
  Date.parse('2022-12-31'),
  Date.parse('2023-06-15'),
];

const earliest = min(times);
const latest = max(times);

Результат автоматически преобразуется в Date.


Особенности сравнения

Сравнение выполняется строго по времени в миллисекундах:

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

Поведение при некорректных значениях

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

import { min } from 'date-fns';

const dates = [
  new Date(2023, 0, 1),
  new Date('invalid'),
];

const result = min(dates);

Практика работы с датами предполагает предварительную валидацию значений.


Пустые массивы

Передача пустого массива приводит к возврату:

Invalid Date
import { max } from 'date-fns';

const result = max([]);
console.log(result); // Invalid Date

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


Использование с разрозненными аргументами

Функции min и max не принимают произвольное количество аргументов напрямую. Передача значений осуществляется только через массив.

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

min(new Date(2023, 1, 1), new Date(2024, 1, 1));

Правильный вариант:

min([new Date(2023, 1, 1), new Date(2024, 1, 1)]);

Работа с массивами, содержащими смешанные типы

Допускается комбинирование Date и числовых значений:

import { max } from 'date-fns';

const result = max([
  new Date(2023, 0, 1),
  1704067200000,
  new Date(2025, 0, 1),
]);

Все значения приводятся к числовому представлению времени перед сравнением.


Внутренняя логика сравнения

Алгоритм работы функций основан на преобразовании каждого элемента:

  1. Приведение к number через valueOf()
  2. Проверка на NaN
  3. Поиск минимального или максимального значения
  4. Возврат Date, созданного из найденного timestamp

Практические сценарии применения

Определение диапазона событий

import { min, max } from 'date-fns';

const events = [
  new Date(2024, 3, 10),
  new Date(2024, 0, 5),
  new Date(2024, 6, 20),
];

const start = min(events);
const end = max(events);

Анализ логов

import { min, max } from 'date-fns';

const logTimes = logs.map(log => new Date(log.timestamp));

const firstEvent = min(logTimes);
const lastEvent = max(logTimes);

Работа с временными диапазонами

import { min, max } from 'date-fns';

const ranges = [
  [new Date(2023, 0, 1), new Date(2023, 5, 1)],
  [new Date(2022, 3, 1), new Date(2022, 8, 1)],
];

const allDates = ranges.flat();

const globalStart = min(allDates);
const globalEnd = max(allDates);

Сравнение с ручной реализацией

Без date-fns аналогичные операции требуют использования Math.min и Math.max с преобразованием:

const dates = [d1, d2, d3];

const minDate = new Date(Math.min(...dates));
const maxDate = new Date(Math.max(...dates));

Подход date-fns устраняет необходимость ручного распыления и преобразований, снижая вероятность ошибок при работе с массивами и типами данных.


Особенности производительности

Обе функции работают за линейное время O(n), где n — количество элементов массива. Дополнительная память не используется сверх временных переменных для хранения текущего минимума или максимума.


Совместимость с другими функциями date-fns

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

  • differenceInDays — анализ диапазонов
  • eachDayOfInterval — генерация последовательностей дат
  • isBefore, isAfter — точечные сравнения
  • format — отображение результата

Композиция таких функций формирует основу обработки временных данных в прикладной логике.