Валидация дат в JavaScript опирается на встроенный объект
Date, который имеет ряд особенностей: нестрогий парсинг
строк, влияние локальной временной зоны и различия между форматами ISO и
«человеческими» форматами. В связке с YupResolver это
становится критичным, поскольку именно схема Yup определяет, какие
значения попадут в форму как валидные.
Базовый тип для работы с датами в Yup:
import * as yup from 'yup';
const schema = yup.object({
birthDate: yup.date()
});
yup.date() принимает любые значения, которые можно
преобразовать в корректную дату через new Date(value). Это
означает, что строка "2024-01-01" будет интерпретирована
как валидная дата, но строка "01/01/2024" может вести себя
по-разному в разных окружениях.
Yup выполняет автоматическое приведение типов (coercion). При работе
с датами это приводит к тому, что входные значения преобразуются в
Date до выполнения проверок.
Пример поведения:
yup.date().isValidSync("2024-01-01"); // true
yup.date().isValidSync("invalid-date"); // false
Однако важно учитывать, что:
Invalid DateДля строгого контроля часто добавляется кастомная проверка:
birthDate: yup
.date()
.typeError('Некорректная дата')
Одна из ключевых задач — ограничение допустимого диапазона дат. Yup
предоставляет методы min и max.
const schema = yup.object({
startDate: yup
.date()
.required()
.min(new Date(2000, 0, 1))
.max(new Date())
});
Особенности:
min и max сравнивают значения через
timestampТипичный кейс — возрастные ограничения:
const today = new Date();
const minBirthDate = new Date(
today.getFullYear() - 18,
today.getMonth(),
today.getDate()
);
const schema = yup.object({
birthDate: yup
.date()
.max(minBirthDate, 'Возраст должен быть не менее 18 лет')
});
Формы часто передают даты в виде строк. Для корректной работы с YupResolver важно нормализовать входные данные.
Yup позволяет использовать трансформации:
birthDate: yup
.date()
.transform((value, originalValue) => {
return originalValue === '' ? null : new Date(originalValue);
})
.nullable()
.required()
Такая схема решает несколько задач:
Invalid DatenullDate в JavaScript всегда хранится в виде количества
миллисекунд с 1 января 1970 UTC, но отображение зависит от локальной
зоны.
При работе с датами в формах это приводит к ошибкам:
"2024-01-01" интерпретируется как UTC или локальное
время в зависимости от окруженияПример проблемы:
new Date("2024-01-01") < new Date("2023-12-31T23:00:00Z");
Решения:
Zconst normalizeDate = (d) => {
const date = new Date(d);
date.setHours(0, 0, 0, 0);
return date;
};
И интегрировать в Yup:
birthDate: yup
.date()
.transform((value, originalValue) =>
originalValue ? normalizeDate(originalValue) : null
)
YupResolver выступает связующим звеном между схемой Yup
и системой валидации форм.
import { useForm } from 'react-hook-form';
import { yupResolver } from '@hookform/resolvers/yup';
const schema = yup.object({
eventDate: yup.date().required()
});
const form = useForm({
resolver: yupResolver(schema)
});
Механизм работы:
resolverYup возвращает структурированные ошибки, которые попадают в
formState.errors.
Пример:
{
eventDate: {
type: "typeError",
message: "eventDate must be a `date` type, but the final value was: Invalid Date"
}
}
Часто полезно унифицировать сообщения:
eventDate: yup
.date()
.typeError('Введите корректную дату')
.required('Дата обязательна')
Хотя Yup ориентирован на Date, он не различает отдельно
дату и время. Это создаёт ограничения при работе с временными
интервалами.
Пример схемы:
const schema = yup.object({
startTime: yup.date().required(),
endTime: yup
.date()
.min(yup.ref('startTime'), 'Конец должен быть позже начала')
});
Особенности:
Yup поддерживает ссылки yup.ref, что позволяет строить
зависимости между полями формы:
const schema = yup.object({
from: yup.date().required(),
to: yup
.date()
.required()
.min(yup.ref('from'), 'Неверный диапазон')
});
Это особенно важно для:
Различие между nullable и optional
критично:
optional() — поле может отсутствоватьnullable() — поле может быть nullКомбинированное использование:
yup
.date()
.nullable()
.notRequired()
Это позволяет корректно обрабатывать пустые значения из форм без
генерации Invalid Date.
Основные проблемы возникают не в YupResolver, а в несогласованности входных данных:
nullDD.MM.YYYY)typeError, из-за чего ошибки становятся
неочевиднымиКорректная схема обычно включает:
transform)typeError)min, max)nullable,
notRequired)