Валидация дат

Компоненты для работы с датами

В MUI для работы с датами используются специализированные компоненты из пакета @mui/x-date-pickers. Основные из них:

  • DatePicker — для выбора одной даты.
  • DateTimePicker — для выбора даты и времени.
  • TimePicker — для выбора только времени.
  • DesktopDatePicker / MobileDatePicker — адаптивные версии, ориентированные на десктоп и мобильные устройства.

Каждый из этих компонентов интегрируется с формами и поддерживает управление состоянием через свойства value и onChange.

Основные подходы к валидации

  1. Встроенная валидация через свойства компонента MUI предоставляет ряд свойств, которые позволяют ограничить выбор даты без дополнительного кода:

    • minDate — минимально допустимая дата.
    • maxDate — максимально допустимая дата.
    • shouldDisableDate — функция, которая возвращает true для дат, которые должны быть недоступны для выбора.

    Пример:

     setSelectedDate(newDate)}
      minDate={new Date('2024-01-01')}
      maxDate={new Date('2024-12-31')}
      shouldDisableDate={(date) => date.getDay() === 0} // запрещаем выбор воскресений
    />

    В этом примере пользователь не сможет выбрать дату до 1 января 2024 и после 31 декабря 2024, а также все воскресенья.

  2. Валидация через onError Все пикеры даты поддерживают свойство onError, которое вызывается при ошибке валидации. Ошибкой считается выбор даты вне диапазона или неправильный формат.

     setSelectedDate(newDate)}
      onEr ror={(reason, value) => {
        console.log(reason); // "minDate", "maxDate", "invalidDate"
      }}
    />

    Возможные значения reason:

    • "invalidDate" — некорректный формат.
    • "minDate" — дата меньше минимально допустимой.
    • "maxDate" — дата больше максимально допустимой.

Интеграция с формами

Для комплексных форм часто используют react-hook-form или Formik. Валидация даты может выполняться как на уровне MUI-компонента, так и через библиотеку форм. При интеграции с react-hook-form:

import { Controller, useForm } from "react-hook-form";
import { DatePicker } from "@mui/x-date-pickers";

const { control, handleSubmit } = useForm();


      date >= new Date('1900-01-01') || "Дата слишком ранняя",
  }}
  render={({ field, fieldState }) => (
    <>
       field.onChange(newValue)}
      />
      {fieldState.error && {fieldState.error.message}}
    
  )}
/>

Этот подход позволяет использовать мощные возможности валидации MUI вместе с проверкой через правила формы, включая кастомные сообщения об ошибках.

Форматы даты и локализация

MUI поддерживает настройку формата даты через AdapterDateFns, AdapterDayjs или AdapterMoment. Это важно для корректной валидации:

import { LocalizationProvider } from "@mui/x-date-pickers";
import { AdapterDayjs } from "@mui/x-date-pickers/AdapterDayjs";


   setSelectedDate(newValue)}
  />

Локализация важна, так как форматы дат (DD/MM/YYYY, MM/DD/YYYY) влияют на интерпретацию ввода и на работу встроенной валидации.

Пользовательская валидация

Иногда встроенные свойства недостаточны, и требуется более сложная логика:

  • Проверка, чтобы выбранная дата была рабочим днем.
  • Ограничение выбора даты в зависимости от другого поля формы.
  • Блокировка праздников или выходных.

Пример пользовательской проверки:

const isHoliday = (date) => {
  const holidays = ['2024-01-01', '2024-12-25'];
  return holidays.includes(date.format('YYYY-MM-DD'));
};

 setSelectedDate(newDate)}
  shouldDisableDate={isHoliday}
/>

shouldDisableDate предоставляет гибкий механизм для блокировки любых дат по правилам бизнеса.

Валидация с использованием minTime и maxTime для DateTimePicker

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

 setSelectedDateTime(newValue)}
  minTime={new Date(0, 0, 0, 9, 0)}  // с 09:00
  maxTime={new Date(0, 0, 0, 18, 0)} // до 18:00
/>

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

Подсказки и сообщения об ошибках

Для улучшения UX MUI позволяет показывать пользователю подсказки о допустимых значениях. Это делается через helperText и error:

 setSelectedDate(newDate)}
  minDate={new Date()}
  maxDate={new Date('2024-12-31')}
  renderInput={(params) => (
    
  )}
/>

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