Валидация дат в Joi строится вокруг строгого контроля допустимых
диапазонов значений. Основной инструмент для работы с датами —
Joi.date(), который позволяет задавать ограничения через
методы min() и max(). Эти методы определяют
нижнюю и верхнюю границы допустимого значения даты, обеспечивая проверку
корректности временных интервалов на уровне схемы данных.
Для работы с датами используется базовый тип:
const schema = Joi.date();
Без дополнительных ограничений такая схема принимает любое валидное
значение даты, которое может быть интерпретировано JavaScript как
Date.
min)Метод min() задаёт нижнюю границу допустимого диапазона.
Значение, переданное в min, становится включительной
границей.
const schema = Joi.date().min('2024-01-01');
В этом случае допустимыми считаются даты, начиная с 1 января 2024 года и позже.
minDate-объекты и временные
метки;Date.parse.Пример использования с объектом Date:
const minDate = new Date('2024-01-01');
const schema = Joi.date().min(minDate);
max)Метод max() задаёт верхнюю границу диапазона допустимых
значений.
const schema = Joi.date().max('2024-12-31');
Здесь валидными считаются все даты до 31 декабря 2024 года включительно.
maxmin;min и maxЧасто ограничения задаются одновременно, формируя закрытый интервал допустимых значений:
const schema = Joi.date().min('2024-01-01').max('2024-12-31');
Такое определение ограничивает дату диапазоном одного календарного года.
Joi сравнивает даты с точностью до миллисекунд. Это означает, что даже при одинаковой календарной дате время может повлиять на результат проверки.
const schema = Joi.date().min('2024-01-01T00:00:00Z');
schema.validate('2024-01-01T00:00:00Z'); // валидно
schema.validate('2023-12-31T23:59:59Z'); // ошибка
При отсутствии временной части в строке используется интерпретация по умолчанию, зависящая от среды выполнения.
В качестве границ допустимо использовать выражения, которые Joi интерпретирует как даты:
const schema = Joi.date().min('now');
Значение 'now' фиксирует нижнюю границу как момент
выполнения валидации. Это полезно для запрета прошедших дат, например
при планировании событий.
Аналогично возможно комбинирование:
const schema = Joi.date().min('now').max('+1y');
Здесь допустимыми считаются даты от текущего момента до одного года вперёд.
При выходе значения за пределы заданного диапазона Joi возвращает
ошибку с кодом date.min или date.max.
Пример структуры ошибки:
{
message: '"value" must be greater than or equal to "2024-01-01"',
type: 'date.min',
context: {
limit: '2024-01-01',
value: '2023-12-31'
}
}
Для верхней границы используется тип date.max.
Сообщения об ошибках можно переопределить через
messages():
const schema = Joi.date()
.min('2024-01-01')
.messages({
'date.min': 'Дата не может быть раньше 2024 года'
});
Это позволяет стандартизировать формат ответов API без обработки ошибок на уровне бизнес-логики.
Joi опирается на объект Date JavaScript, поэтому
временные зоны интерпретируются в зависимости от среды выполнения. При
работе с ISO-строками рекомендуется явно указывать UTC:
Joi.date().min('2024-01-01T00:00:00Z');
Это снижает риск расхождений при сравнении дат в распределённых системах.
Допустимо использование UNIX timestamp (миллисекунды):
const schema = Joi.date().min(1704067200000);
Такой подход часто используется при интеграции с системами, где даты хранятся в числовом формате.
Ограничения min и max применяются
независимо от контекста объекта, но часто используются внутри вложенных
структур:
const schema = Joi.object({
startDate: Joi.date().required(),
endDate: Joi.date().min(Joi.ref('startDate'))
});
В этом случае endDate должен быть не раньше
startDate, что формирует динамическое ограничение на основе
значения другого поля.
Методы min и max часто используются вместе
с:
required() — обязательность поля;iso() — строгий формат ISO 8601;precision() — ограничение точности времени.Пример комплексной схемы:
const schema = Joi.date()
.iso()
.min('2024-01-01')
.max('2024-12-31')
.required();
Неправильный формат строки
Joi.date().min('01-01-2024'); // может быть интерпретировано некорректно
Корректный вариант — ISO формат:
Joi.date().min('2024-01-01');
Игнорирование временной части
Joi.date().min('2024-01-01');
Такое ограничение может пропускать значения, близкие к границе, но отличающиеся по времени.
Без min и max дата считается валидной, если
она может быть преобразована в корректный объект Date. Это
создаёт максимально широкую область допустимых значений и переносит
ответственность за ограничения на уровень бизнес-логики.
Использование минимальных и максимальных дат в Joi формирует слой первичной защиты данных. Проверка на уровне схемы предотвращает:
Такая модель валидации особенно критична в системах с расписаниями, бронированиями и финансовыми операциями, где временные границы являются частью бизнес-правил.