Массивы дат в Day.js обрабатываются через комбинацию стандартных методов массива JavaScript и возможностей самого Day.js, поскольку библиотека не предоставляет отдельного специализированного API для коллекций дат. Основной подход заключается в преобразовании элементов массива в экземпляры Day.js, выполнении операций сравнения, фильтрации, сортировки и последующего преобразования обратно в нужный формат.
Работа с датами начинается с приведения входных данных к единому типу. Day.js создаёт неизменяемые объекты, поэтому каждая операция возвращает новый экземпляр.
import dayjs from "dayjs";
const dates = [
"2026-01-01",
"2026-03-15",
"2025-12-31"
];
const parsed = dates.map(d => dayjs(d));
После преобразования становится доступен полный набор методов сравнения и манипуляций.
Сортировка выполняется через Array.prototype.sort() с
использованием методов isBefore и isAfter.
const sorted = parsed.sort((a, b) => {
if (a.isBefore(b)) return -1;
if (a.isAfter(b)) return 1;
return 0;
});
Более компактная форма с числовым сравнением через
valueOf():
const sorted = parsed.sort((a, b) => a.valueOf() - b.valueOf());
valueOf() возвращает timestamp, что делает сравнение
прямолинейным и эффективным.
Фильтрация массивов дат часто строится вокруг проверки попадания в интервал.
const start = dayjs("2026-01-01");
const end = dayjs("2026-02-01");
const filtered = parsed.filter(date =>
(date.isAfter(start) || date.isSame(start)) &&
(date.isBefore(end) || date.isSame(end))
);
Для упрощения логики используется метод isBetween,
доступный через plugin isBetween.
import isBetween from "dayjs/plugin/isBetween";
dayjs.extend(isBetween);
const filtered = parsed.filter(date =>
date.isBetween(start, end, null, "[]")
);
Квадратные скобки задают включительность границ диапазона.
Массив дат можно свести к экстремумам через сравнение timestamp.
const minDate = parsed.reduce((min, current) =>
current.isBefore(min) ? current : min
);
const maxDate = parsed.reduce((max, current) =>
current.isAfter(max) ? current : max
);
Альтернативный вариант через числовые значения:
const minDate = parsed.reduce((min, current) =>
current.valueOf() < min.valueOf() ? current : min
);
Уникализация выполняется через нормализацию к строковому представлению или timestamp.
const unique = Array.from(
new Map(parsed.map(d => [d.format("YYYY-MM-DD"), d])).values()
);
Вариант через Set:
const unique = Array.from(
new Map(parsed.map(d => [d.valueOf(), d])).values()
);
Выбор ключа зависит от требуемой точности (дата или дата-время).
Группировка позволяет структурировать массив по дням, месяцам или годам.
const groupedByDay = parsed.reduce((acc, date) => {
const key = date.format("YYYY-MM-DD");
if (!acc[key]) acc[key] = [];
acc[key].push(date);
return acc;
}, {});
const groupedByMonth = parsed.reduce((acc, date) => {
const key = date.format("YYYY-MM");
if (!acc[key]) acc[key] = [];
acc[key].push(date);
return acc;
}, {});
Массивы дат часто формируются динамически с шагом в один день или другой интервал.
const start = dayjs("2026-01-01");
const end = dayjs("2026-01-10");
const range = [];
let current = start;
while (current.isBefore(end) || current.isSame(end)) {
range.push(current);
current = current.add(1, "day");
}
Каждая итерация создаёт новый объект Day.js, сохраняя неизменяемость.
Проверка пересечений или различий между наборами дат выполняется через сравнение нормализованных значений.
const a = parsed.map(d => d.format("YYYY-MM-DD"));
const b = otherParsed.map(d => d.format("YYYY-MM-DD"));
const intersection = a.filter(x => b.includes(x));
Для оптимизации используется Set:
const setB = new Set(b);
const intersection = a.filter(x => setB.has(x));
Работа с временными интервалами часто требует преобразования дат в timestamp.
const timestamps = parsed.map(d => d.valueOf());
const diffs = timestamps.slice(1).map((t, i) =>
t - timestamps[i]
);
Полученные значения представляют разницу между соседними датами в миллисекундах.
Операции трансформации применяются к каждому элементу массива через
map.
const shifted = parsed.map(d => d.add(7, "day"));
Аналогично возможно уменьшение интервала:
const shiftedBack = parsed.map(d => d.subtract(3, "month"));
Приведение всех дат к единому формату используется перед хранением или сравнением.
const normalized = parsed.map(d => d.startOf("day"));
Или нормализация к UTC:
const utcNormalized = parsed.map(d => d.utc());
При работе с интервалами дат массивы могут содержать пересекающиеся периоды.
const ranges = [
[dayjs("2026-01-01"), dayjs("2026-01-05")],
[dayjs("2026-01-04"), dayjs("2026-01-10")]
];
Обработка выполняется через последовательное сравнение границ:
const merged = ranges.sort((a, b) => a[0] - b[0]).reduce((acc, range) => {
if (!acc.length) return [range];
const last = acc[acc.length - 1];
if (range[0].isBefore(last[1])) {
last[1] = dayjs.max(last[1], range[1]);
} else {
acc.push(range);
}
return acc;
}, []);
Формирование структуры календаря требует распределения дат по неделям.
const weeks = [];
let week = [];
parsed.forEach(date => {
week.push(date);
if (date.day() === 0) {
weeks.push(week);
week = [];
}
});
if (week.length) weeks.push(week);
При наличии пропусков между датами применяется заполнение промежутков.
const start = parsed[0];
const end = parsed[parsed.length - 1];
const filled = [];
let current = start;
while (current.isBefore(end) || current.isSame(end)) {
filled.push(current);
current = current.add(1, "day");
}
Производительность операций зависит от минимизации повторных парсингов и конверсий. Эффективная схема предполагает:
valueOf() для сравненийSet для поиска и исключенийformat() внутри цикловconst map = new Map(
parsed.map(d => [d.valueOf(), d])
);
Такая структура снижает стоимость операций поиска и объединения.