Date Utils
Central Design System включает набор функций для работы с нативным JS Date: форматирование по маске, парсинг строк, арифметика, сравнение и календарные вычисления. Отдельная библиотека дат (dayjs, date-fns) для типовых задач не нужна. Эти же функции используют компоненты даты и времени — CdsDateInput, CdsDatePicker, CdsTimePicker, — поэтому маски формата в утилитах и компонентах совпадают.
Функции принимают Date, метку времени (миллисекунды) или строку даты, возвращают нативный Date и не изменяют переданные аргументы — результат всегда новый объект.
Подключение
Утилиты экспортируются из пакета неймспейсом utils:
import { utils } from '@central-design-system/components';
const { formatDate, addToDate } = utils;
formatDate(new Date(2026, 7, 18), 'DD.MM.YYYY'); // '18.08.2026'Форматирование — formatDate
formatDate(value, mask, dateLocale?) превращает дату в строку по маске:
const { formatDate } = utils;
formatDate(new Date(2026, 7, 18, 14, 30), 'DD.MM.YYYY HH:mm'); // '18.08.2026 14:30'
formatDate(Date.now(), 'D MMM YYYY'); // '18 Авг 2026'
formatDate(new Date(2026, 7, 18), 'dddd'); // 'Вторник'Без маски используется ISO-подобный формат YYYY-MM-DDTHH:mm:ss.SSSZ. Для невалидного значения функция возвращает undefined.
Названия месяцев и дней недели по умолчанию берутся из русской date-локали. Чтобы вывести их на другом языке, передайте date-локаль третьим аргументом — встроенные лежат в экспорте locales:
import { locales, utils } from '@central-design-system/components';
utils.formatDate(new Date(2026, 7, 18), 'dddd, D MMMM', locales.enDate);
// 'Tuesday, 18 August'Свой язык подключается объектом типа TDateLocale — теми же полями, что у locales.ruDate. Подробнее о date-локалях — в гайде Интернационализация.
Токены формата
| Единица | Токен | Результат |
|---|---|---|
| Год | YY / YYYY | 26 / 2026 |
| Месяц | M / MM | 8 / 08 |
| Месяц (название) | MMM / MMMM | Авг / Август |
| Квартал | Q / Qo | 3 / 3rd |
| День месяца | D / Do / DD | 18 / 18th / 18 |
| День года | DDD / DDDD | 230 / 230 (с нулями до 3 знаков) |
| День недели | d | 2 (0 — воскресенье) |
| День недели (название) | dd / ddd / dddd | Вт / Вт / Вторник |
| День недели (ISO) | E | 2 (1 — понедельник, 7 — воскресенье) |
| Неделя года | w / ww | 34 / 34 |
| Час (0–23) | H / HH | 14 / 14 |
| Час (1–12) | h / hh | 2 / 02 |
| Минута | m / mm | 30 / 30 |
| Секунда | s / ss | 5 / 05 |
| Доли секунды | S / SS / SSS | 1 / 12 / 123 |
| Часовой пояс | Z / ZZ | +03:00 / +0300 |
| Меридием | A / a / aa | PM / pm / p.m. |
| Unix-время | X / x | секунды / миллисекунды |
Порядковые суффиксы (Do, Qo) — английские (1st, 2nd…) независимо от локали.
Произвольный текст в маске экранируется квадратными скобками:
formatDate(new Date(2026, 7, 18), '[Сегодня] DD.MM'); // 'Сегодня 18.08'Парсинг — extractDate и splitDate
extractDate(str, mask, dateLocale?) разбирает строку по маске и возвращает Date:
const { extractDate } = utils;
extractDate('21.03.1985', 'DD.MM.YYYY'); // Date: 21 марта 1985
extractDate('2019-10-29 23:12', 'YYYY-MM-DD HH:mm'); // Date: 29 октября 2019, 23:12Названия месяцев и дней в строке распознаются через date-локаль — как и в formatDate, по умолчанию русскую.
Несуществующий день переполняется по правилам нативного Date: extractDate('30.02.2024', 'DD.MM.YYYY') даст 1 марта 2024. Когда нужна строгая проверка ввода, отформатируйте результат обратно и сравните со строкой:
const strict = (str: string, mask: string) => formatDate(extractDate(str, mask), mask) === str;
strict('18.08.2026', 'DD.MM.YYYY'); // true
strict('30.02.2024', 'DD.MM.YYYY'); // false — переполнилось в 01.03.2024Если Date создавать не нужно, splitDate(str, mask, dateLocale?) разбирает строку на составные части — объект IRawDate с полями year, month, day, hour, minute, second, millisecond (ненайденные — null):
const { splitDate } = utils;
splitDate('18.08.2026', 'DD.MM.YYYY');
// { year: 2026, month: 8, day: 18, hour: null, … }Создание и изменение
buildDate
buildDate(modified, utc?) — текущий момент с заменой отдельных частей. Удобно, когда нужно «сейчас, но в 15:00» или «сегодня, но в 2010 году»:
const { buildDate } = utils;
buildDate({ year: 2010, day: 5, hour: 15 });
// текущие месяц, минуты и секунды; год 2010, число 5, час 15Поддерживаемые поля объекта: year, month (1–12), day (или date), hour, minute, second, millisecond.
adjustDate
adjustDate(date, modified, utc?) — то же самое, но для произвольной даты:
const { adjustDate } = utils;
adjustDate(new Date(2026, 10, 2), { year: 2010, month: 2 });
// Date: 2 февраля 2010Обратите внимание: month здесь 1-based (февраль — 2), в отличие от конструктора Date.
addToDate / subtractFromDate
Прибавляют и вычитают интервалы. Поля объекта — те же, но означают не «установить», а «сколько прибавить»:
const { addToDate, subtractFromDate } = utils;
addToDate(new Date(2026, 2, 7), { day: 7, month: 1 }); // Date: 14 апреля 2026
subtractFromDate(new Date(2026, 2, 7), { hour: 24 }); // Date: 6 марта 2026startOfDate / endOfDate
Начало и конец периода — года, месяца, дня, часа, минуты или секунды:
const { startOfDate, endOfDate } = utils;
startOfDate(new Date(2026, 7, 18, 14, 30), 'year'); // Date: 1 января 2026, 00:00:00.000
endOfDate(new Date(2026, 7, 18, 14, 30), 'month'); // Date: 31 августа 2026, 23:59:59.999Единица периода: 'year', 'month', 'day', 'hour', 'minute', 'second' (форма множественного числа тоже принимается).
Сравнение и диапазоны
isSameDate
Сравнивает даты с точностью до единицы: 'year' — только год, 'month' — месяц и год, 'day' — календарный день и так далее. Без единицы сравниваются метки времени целиком.
const { isSameDate } = utils;
isSameDate(new Date(2026, 7, 1), new Date(2026, 7, 30), 'month'); // true
isSameDate(new Date(2026, 7, 1), new Date(2026, 7, 30), 'day'); // falsegetDateDiff
Разница между датами в выбранной единице (по умолчанию — дни):
const { getDateDiff } = utils;
getDateDiff(new Date(2026, 4, 12), new Date(2026, 3, 8)); // 34 (дня)
getDateDiff(new Date(2026, 4, 12), new Date(2026, 3, 8), 'months'); // 1isBetweenDates / getDateBetween
isBetweenDates(date, from, to, opts?) проверяет попадание в диапазон. По умолчанию границы не включаются; опции inclusiveFrom и inclusiveTo включают их, onlyDate: true сравнивает только календарные дни, игнорируя время:
const { isBetweenDates } = utils;
isBetweenDates(date, from, to); // строгий диапазон
isBetweenDates(date, from, to, { inclusiveFrom: true, inclusiveTo: true, onlyDate: true });getDateBetween(date, min, max) прижимает дату к диапазону: вернёт саму дату, если она внутри, иначе — ближайшую границу:
const { getDateBetween } = utils;
getDateBetween(new Date(2025, 0, 1), new Date(2026, 0, 1), new Date(2026, 11, 31));
// Date: 1 января 2026 — дата ниже минимума, вернулась граница mingetMinDate / getMaxDate
Наименьшая и наибольшая из набора дат. Возвращают метку времени (number) — оберните в new Date(), если нужен объект даты:
const { getMinDate, getMaxDate } = utils;
const min = getMinDate(new Date(2026, 6, 24), new Date(2026, 5, 20), new Date(2026, 6, 26));
new Date(min); // Date: 20 июня 2026
const dates = [/* Date[] */];
const max = getMaxDate(dates[0], ...dates.slice(1));Календарь
const { getDayOfWeek, getWeekOfYear, getDayOfYear, daysInMonth } = utils;
getDayOfWeek(new Date(2026, 7, 16)); // 7 — воскресенье (ISO: 1 — понедельник)
getWeekOfYear(new Date(2026, 0, 4)); // 1 — номер ISO-недели в году
getDayOfYear(new Date(2026, 1, 4)); // 35 — порядковый день в году
daysInMonth(new Date(2024, 1, 15)); // 29 — февраль високосного годаПрочее
isValidDate
Проверяет, парсится ли значение в дату:
const { isValidDate } = utils;
isValidDate('2026-08-18'); // true
isValidDate('не дата'); // falseПроверка синтаксическая — она не ловит несуществующие календарные дни (см. splitDate выше).
cloneDate
Копия даты. Пригодится перед передачей в чужой код, который может мутировать объект (сами утилиты CDS аргументы не изменяют):
const { cloneDate } = utils;
const copy = cloneDate(original);inferDateFormat
Определяет форму значения — удобно, чтобы вернуть результат в том же виде, в котором пришло значение:
const { inferDateFormat } = utils;
inferDateFormat(new Date()); // 'date'
inferDateFormat(1787059805000); // 'number'
inferDateFormat('18.08.2026'); // 'string'