Валидация дат от пользователя

Работа с датами, полученными от пользователя, требует строгого контроля формата и корректности значений. В JavaScript любые некорректные данные, переданные в конструкторы дат или функции парсинга, могут приводить к неочевидным результатам: Invalid Date, NaN, смещения временных зон или логических ошибок в вычислениях. Библиотека Day.js предоставляет компактный и предсказуемый механизм для проверки и обработки таких значений.


Базовая проверка корректности даты

В Day.js любой созданный объект даты может быть проверен на валидность с помощью метода:

dayjs().isValid()

При передаче пользовательского ввода ключевым становится результат парсинга:

const date = dayjs('2026-01-15');
date.isValid(); // true

Некорректные строки автоматически помечаются как невалидные:

const date = dayjs('не дата');
date.isValid(); // false

Внутренняя модель Day.js не выбрасывает исключения при ошибках парсинга — вместо этого возвращается объект с флагом валидности.


Поведение при некорректном вводе

Day.js использует мягкий парсинг, аналогичный native Date, но с более предсказуемым API. При невозможности интерпретации строки создаётся объект с состоянием invalid:

const d1 = dayjs('');
const d2 = dayjs(null);
const d3 = dayjs(undefined);

d1.isValid(); // false
d2.isValid(); // false
d3.isValid(); // false

Особое поведение наблюдается при частично корректных строках:

dayjs('2026-13-40').isValid(); // false
dayjs('2026-02-30').isValid(); // false

Строгая валидация через формат

Для контроля пользовательского ввода применяется плагин customParseFormat, который позволяет задавать точный формат строки и исключать неоднозначные значения.

Подключение плагина:

import dayjs from 'dayjs';
import customParseFormat from 'dayjs/plugin/customParseFormat';

dayjs.extend(customParseFormat);

Пример строгого разбора:

dayjs('15/01/2026', 'DD/MM/YYYY', true).isValid(); // true
dayjs('15-01-2026', 'DD/MM/YYYY', true).isValid(); // false

Третий аргумент true включает строгий режим, при котором:

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

Валидация ISO-форматов

ISO 8601 является наиболее безопасным форматом для передачи дат от пользователя или API. Day.js корректно обрабатывает его без дополнительных плагинов:

dayjs('2026-01-15T10:30:00Z').isValid(); // true

При этом отклонения от стандарта приводят к невалидному результату:

dayjs('2026/01/15').isValid(); // false
dayjs('15-01-2026T10:30').isValid(); // false

Предварительная проверка строки перед парсингом

Валидация на уровне строки часто используется для фильтрации очевидно некорректных данных до передачи в Day.js. Это снижает нагрузку и повышает предсказуемость обработки.

Пример проверки через регулярное выражение:

const isoRegex = /^\d{4}-\d{2}-\d{2}$/;

function isValidDateString(value) {
  return isoRegex.test(value) && dayjs(value).isValid();
}

Такой подход отделяет синтаксическую проверку от семантической.


Проверка диапазонов дат

Корректная дата может быть формально валидной, но выходить за допустимые бизнес-ограничения. Day.js не навязывает диапазоны, поэтому проверка выполняется вручную.

Пример ограничения по диапазону:

const date = dayjs('2026-01-15');

const min = dayjs('2000-01-01');
const max = dayjs('2030-12-31');

const inRange =
  date.isValid() &&
  date.isAfter(min) &&
  date.isBefore(max);

Методы:

  • isAfter()
  • isBefore()
  • isSame()

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


Работа с пользовательским вводом формата “дата + время”

Ввод с временем требует более строгой схемы:

const format = 'DD.MM.YYYY HH:mm';

const date = dayjs('15.01.2026 14:45', format, true);

date.isValid(); // true

Ошибки возникают при малейшем несоответствии:

dayjs('15.01.2026 14:60', format, true).isValid(); // false
dayjs('15.01.2026', format, true).isValid(); // false

Особенности пустых и частично заполненных значений

В пользовательских формах часто встречаются неполные данные:

dayjs('').isValid();        // false
dayjs('   ').isValid();     // false
dayjs(null).isValid();      // false

При обработке форм такие значения обычно фильтруются до парсинга:

function normalizeInput(value) {
  return typeof value === 'string' ? value.trim() : '';
}

Сравнение с native Date

Встроенный Date возвращает объект даже при ошибке парсинга:

new Date('invalid'); // Invalid Date

Однако проверка требует отдельного вызова:

isNaN(new Date('invalid').getTime()); // true

Day.js упрощает этот процесс:

dayjs('invalid').isValid(); // false

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


Обработка ошибок в цепочках операций

В Day.js большинство методов возвращают новый объект, даже если исходная дата невалидна. Поэтому проверка валидности должна выполняться на раннем этапе:

const result = dayjs('invalid')
  .add(5, 'day')
  .format('YYYY-MM-DD');

dayjs('invalid').isValid(); // false

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


Типовые сценарии фильтрации пользовательских дат

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

const inputs = [
  '2026-01-01',
  'не дата',
  '2026-02-30',
  '2025-12-31'
];

const validDates = inputs
  .map(d => dayjs(d))
  .filter(d => d.isValid());

Результат содержит только корректные даты, пригодные для дальнейших вычислений.


Контроль качества данных в формах

При работе с пользовательскими интерфейсами распространена стратегия многоуровневой проверки:

  1. Синтаксическая проверка строки
  2. Строгий парсинг Day.js
  3. Проверка диапазонов
  4. Проверка бизнес-логики (например, дата не раньше текущей)

Пример комбинированной логики:

function validateDate(value) {
  const date = dayjs(value, 'YYYY-MM-DD', true);

  return (
    date.isValid() &&
    date.isAfter(dayjs('2000-01-01')) &&
    date.isBefore(dayjs('2100-01-01'))
  );
}

Нормализация некорректных значений

В некоторых системах требуется не отбрасывать ошибочные даты, а заменять их на значение по умолчанию:

function safeDate(value) {
  const date = dayjs(value);

  return date.isValid() ? date : dayjs('1970-01-01');
}

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


Работа с временными зонами и валидацией

При использовании плагина utc или timezone возможны дополнительные источники некорректности:

  • неправильный offset;
  • некорректный формат зоны;
  • конфликт локального и UTC времени.

Пример:

import utc from 'dayjs/plugin/utc';
dayjs.extend(utc);

dayjs.utc('2026-01-15T10:00:00Z').isValid(); // true
dayjs.utc('2026-01-15T25:00:00Z').isValid(); // false

Итоговые особенности механизма валидации

Модель проверки дат в Day.js строится на нескольких принципах:

  • отсутствие исключений при ошибках парсинга;
  • явный флаг валидности через isValid();
  • строгий режим через customParseFormat;
  • независимость валидации от преобразований;
  • возможность комбинировать с ручными бизнес-правилами.

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