Работа с пользовательским вводом дат в приложениях на JavaScript требует строгого контроля корректности данных, поскольку любая неоднозначность в формате даты приводит к логическим ошибкам, сбоям фильтрации и некорректным вычислениям. В экосистеме JavaScript одной из наиболее удобных библиотек для обработки дат выступает Day.js, предоставляющая лаконичный API и предсказуемое поведение при парсинге и валидации.
Пользовательский ввод даты практически всегда является источником неоднородных данных:
2026-01-24, 24/01/2026,
Jan 24 2026)24-01, 01/2026)32/13/2026, abcd)Даже при наличии UI-календаря данные могут приходить из API, импортов CSV или внешних сервисов, где контроль формата отсутствует. Поэтому валидация не может опираться только на фронтенд, она должна выполняться на уровне бизнес-логики.
В Day.js базовая валидация строится вокруг функции
dayjs() и метода isValid().
Любая строка преобразуется в объект даты:
import dayjs from 'dayjs';
const date = dayjs('2026-01-24');
console.log(date.isValid()); // true
При невозможности интерпретации строки объект считается невалидным:
const date = dayjs('invalid-date');
console.log(date.isValid()); // false
Стандартный парсер Day.js:
Это удобно, но опасно при строгой валидации пользовательского ввода, так как строка может быть интерпретирована неожиданным образом.
Для строгого контроля используется плагин
customParseFormat.
import dayjs from 'dayjs';
import customParseFormat from 'dayjs/plugin/customParseFormat';
dayjs.extend(customParseFormat);
const date = dayjs('24/01/2026', 'DD/MM/YYYY', true);
console.log(date.isValid()); // true
Третий аргумент true включает строгий режим:
dayjs('24-01-2026', 'DD/MM/YYYY', true).isValid(); // false
dayjs('32/01/2026', 'DD/MM/YYYY', true).isValid(); // false
Перед парсингом часто выполняется предварительная нормализация строки:
function normalizeInput(input) {
return input.trim().replace(/\s+/g, ' ');
}
function normalizeDateString(input) {
return input
.trim()
.replace(/\./g, '/')
.replace(/-/g, '/');
}
После нормализации строка становится более предсказуемой для парсинга.
В реальных системах пользователи могут вводить дату в разных форматах. Подход заключается в последовательной проверке:
const formats = ['DD/MM/YYYY', 'YYYY-MM-DD', 'MM-DD-YYYY'];
function parseDate(input) {
for (const format of formats) {
const parsed = dayjs(input, format, true);
if (parsed.isValid()) {
return parsed;
}
}
return null;
}
Такой подход позволяет централизовать поддержку нескольких форматов без потери строгой валидации.
После успешного парсинга важно ограничивать допустимые значения.
const minDate = dayjs('2000-01-01');
const maxDate = dayjs('2030-12-31');
function isInRange(date) {
return date.isAfter(minDate) && date.isBefore(maxDate);
}
function isInRangeInclusive(date) {
return (
(date.isAfter(minDate) || date.isSame(minDate)) &&
(date.isBefore(maxDate) || date.isSame(maxDate))
);
}
Некоторые значения формально соответствуют формату, но логически невозможны:
Day.js автоматически валидирует такие случаи при строгом парсинге:
dayjs('31/02/2026', 'DD/MM/YYYY', true).isValid(); // false
При этом в нестрогом режиме возможны неожиданные «перепрыгивания» дат, что требует осторожности.
Проблемы валидации часто связаны не только с форматом, но и с часовыми поясами.
import utc from 'dayjs/plugin/utc';
dayjs.extend(utc);
const date = dayjs.utc('2026-01-24T10:00:00');
console.log(date.isValid());
Использование UTC позволяет избежать:
В реальных приложениях проверка обычно интегрируется в форму ввода.
function validateDateInput(value) {
const parsed = dayjs(value, 'DD/MM/YYYY', true);
if (!parsed.isValid()) {
return { valid: false, error: 'Некорректный формат даты' };
}
if (!isInRange(parsed)) {
return { valid: false, error: 'Дата вне допустимого диапазона' };
}
return { valid: true, date: parsed };
}
Такой подход разделяет:
При интерактивном вводе (маски ввода) данные могут быть неполными:
24/012026-01В таких случаях полная валидация не выполняется. Вместо этого используется промежуточная проверка:
function isPotentialDate(input) {
return /^[0-9/.-]+$/.test(input);
}
Это позволяет различать:
dayjs('2026-13-40') // может дать неожиданный результат без проверки
isValid()Объект Day.js всегда создаётся, но не всегда содержит корректную дату.
dayjs('24/01/2026') // интерпретация зависит от окружения
Сравнение дат без нормализации приводит к смещению логики.
При передаче даты на сервер необходимо:
const payload = {
date: parsed.toISOString()
};
При работе с массивами дат часто используется фильтрация:
const validDates = inputs
.map(v => dayjs(v, 'DD/MM/YYYY', true))
.filter(d => d.isValid());
Это позволяет очистить данные перед дальнейшей обработкой.
Перед сравнением всегда требуется проверка корректности:
if (a.isValid() && b.isValid()) {
console.log(a.isBefore(b));
}
Без этого сравнение может давать некорректные результаты даже при создании объекта из ошибочной строки.
Комбинированный подход к обработке пользовательского ввода обычно включает:
customParseFormatisValid()Такой слой валидации делает работу с датами предсказуемой даже при хаотичном пользовательском вводе.