Минимальная и максимальная дата

Работа с датами в схемах валидации требует точного контроля границ допустимых значений. В библиотеке Yup это реализуется через методы ограничения диапазона — min() и max(), применяемые к типу date(). Эти методы позволяют задавать нижнюю и верхнюю границу допустимой даты и активно используются в формах, API-валидации и бизнес-логике.


Базовая схема работы с датами

Тип date() в Yup создаёт валидатор, который ожидает значение, приводимое к объекту Date.

import * as yup from 'yup';

const schema = yup.object({
  birthday: yup.date()
});

На этом уровне проверяется только корректность даты как типа данных. Ограничения диапазона отсутствуют.


Ограничение минимальной даты

Метод min() задаёт минимально допустимую дату. Любое значение, которое меньше указанной границы, считается невалидным.

const schema = yup.object({
  startDate: yup.date().min(new Date('2024-01-01'))
});

В этом примере все даты ранее 1 января 2024 года будут отклонены.

Поведение сравнения

  • сравнение выполняется по timestamp (getTime())
  • временная зона учитывается через внутреннее представление Date
  • строковые значения автоматически приводятся к Date

Ограничение максимальной даты

Метод max() задаёт верхнюю границу допустимого диапазона.

const schema = yup.object({
  endDate: yup.date().max(new Date('2024-12-31'))
});

Любая дата позже 31 декабря 2024 года будет считаться невалидной.


Комбинирование min и max

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

const schema = yup.object({
  eventDate: yup.date()
    .min(new Date('2024-01-01'))
    .max(new Date('2024-12-31'))
});

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


Валидация относительных дат

Границы могут задаваться динамически относительно текущего времени.

const schema = yup.object({
  futureDate: yup.date()
    .min(new Date())
});

Здесь запрещаются любые прошедшие даты.

Аналогично можно ограничивать прошлое:

const schema = yup.object({
  pastDate: yup.date()
    .max(new Date())
});

Использование функций для вычисления границ

Для предотвращения «застывших» значений границы часто вычисляются во время выполнения схемы.

const schema = yup.object({
  bookingDate: yup.date()
    .min(() => new Date(Date.now() + 24 * 60 * 60 * 1000))
});

В этом случае минимальная дата всегда будет «завтра», независимо от момента загрузки модуля.


Кастомизация сообщений об ошибках

min() и max() поддерживают передачу сообщений валидации вторым аргументом.

const schema = yup.object({
  ageDate: yup.date()
    .min(new Date('2000-01-01'), 'Дата слишком ранняя')
    .max(new Date('2025-01-01'), 'Дата выходит за допустимый диапазон')
});

Сообщения позволяют явно отделять бизнес-логику от пользовательской интерпретации ошибки.


Работа со строковыми датами

Yup принимает строки, если они приводимы к корректной дате.

yup.date().min('2024-01-01').max('2024-12-31')

Однако поведение зависит от реализации Date.parse(), поэтому при строгой валидации предпочтительнее использовать объекты Date.


Особенности сравнения и временные зоны

Внутреннее сравнение происходит через числовое значение времени.

Ключевые особенности:

  • сравнение не учитывает формат отображения даты
  • время 00:00:00 может влиять на результат при пограничных значениях
  • локальная временная зона может смещать дату при конвертации строк

Пример потенциальной проблемы:

yup.date().min(new Date('2024-01-01'))

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


Использование с формами

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

const schema = yup.object({
  checkIn: yup.date().required().min(new Date()),
  checkOut: yup.date()
    .min(yup.ref('checkIn'))
});

Здесь checkOut не может быть раньше checkIn, что реализует зависимую валидацию между полями.


Валидация через ссылки на другие поля

Yup поддерживает динамические зависимости через ref().

yup.date().min(yup.ref('startDate'))

Такой подход используется для:

  • диапазонов бронирования
  • логики «от/до»
  • временных интервалов в календарях

Граничные случаи и нюансы

Равенство границе

Значение, равное min или max, считается валидным.

yup.date().min(new Date('2024-01-01'))

Дата 1 января 2024 года допустима.


Null и undefined

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

  • required() делает поле обязательным
  • без required() допускается undefined
  • nullable() допускает null
yup.date().nullable().min(new Date('2024-01-01'))

Порядок вызова методов

Хотя Yup допускает цепочку вызовов в любом порядке, логически важно учитывать последовательность ограничений, особенно при комбинировании с transform() или when().


Условная валидация диапазонов

Метод when() позволяет менять границы динамически.

yup.object({
  type: yup.string(),
  date: yup.date().when('type', {
    is: 'event',
    then: schema => schema.min(new Date('2024-01-01')),
    otherwise: schema => schema.max(new Date())
  })
});

Так формируются разные диапазоны в зависимости от состояния данных.


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

Ограничения min() и max() используются в задачах:

  • календарные бронирования
  • регистрация по возрасту (через даты рождения)
  • фильтрация аналитических периодов
  • ограничения API-запросов по датам
  • бизнес-правила с временными окнами

Стабильность и воспроизводимость

При использовании фиксированных дат в схемах важно учитывать момент инициализации модуля. Если границы вычисляются один раз при загрузке, они могут устареть при длительной работе приложения. Использование функций в min() и max() решает эту проблему, обеспечивая актуальность значений на момент валидации.