Формат ISO 8601 представляет собой международный стандарт представления дат и времени. Он используется для унификации временных значений в API, базах данных и межсервисном взаимодействии. В контексте JavaScript и серверной валидации особое значение имеет корректная проверка строк, содержащих даты в этом формате, поскольку некорректные значения приводят к ошибкам сериализации, неверной сортировке и логическим сбоям в бизнес-логике.
Валидация ISO-строк в библиотеке Joi строится вокруг строгих правил
распознавания формата, а также возможности преобразования строки в
объект Date для дальнейшей работы.
Библиотека Joi предоставляет несколько механизмов для работы с ISO-датами, зависящих от типа схемы:
Joi.string().isoDate() — проверка строки на
соответствие ISO 8601Joi.date().iso() — строгая проверка даты в ISO-формате
с преобразованием.strict(), .raw() и
.custom() для расширенной логикиОсновное различие между строковой и датовой валидацией заключается в
том, что строковая проверка оставляет значение в исходном виде, тогда
как Joi.date() выполняет парсинг.
При использовании строковой схемы:
import Joi from 'joi';
const schema = Joi.object({
createdAt: Joi.string().isoDate()
});
В данном случае допустимыми значениями считаются строки, соответствующие стандарту ISO 8601:
2026-05-102026-05-10T14:30:00Z2026-05-10T14:30:00+06:00Любые отклонения, включая нестандартные разделители или локальные форматы, приводят к ошибке валидации.
Особенность isoDate() заключается в том, что проверяется
именно структура строки, без преобразования в объект
Date.
Более строгий и функциональный подход основан на типе
date:
const schema = Joi.object({
createdAt: Joi.date().iso()
});
В этом случае происходит:
DateВходные данные могут быть как строкой, так и Date,
однако при несоответствии формату выбрасывается ошибка.
Ключевые различия можно описать через поведение:
| Поведение | string().isoDate() | date().iso() |
|---|---|---|
| Проверка формата | Да | Да |
| Преобразование в Date | Нет | Да |
| Сохранение исходного значения | Да | Нет |
| Поддержка операций с датой | Нет | Да |
Выбор подхода зависит от архитектуры системы. Валидация на уровне
строк применяется в API-слоях, тогда как date().iso()
используется в доменной логике.
ISO 8601 включает несколько форматов, которые Joi способен распознавать:
2026-05-10
2026-05-10T14:30:00Z
2026-05-10T14:30:00+06:00
2026-05-10T14:30:00.123Z
Все эти варианты считаются валидными при использовании
.isoDate() или .date().iso().
При использовании Joi.date().iso() происходит
автоматическая нормализация временной зоны в объекте Date.
Это означает:
+06:00 преобразуется в UTC-времяВажно учитывать, что Date в JavaScript не хранит
исходную временную зону, что может приводить к потере контекста.
Типовые причины отклонения значений:
TT10.05.2026)Пример невалидного значения:
2026/05/10 14:30
Joi позволяет расширять ISO-проверки дополнительными ограничениями:
const schema = Joi.object({
createdAt: Joi.date().iso().min('2020-01-01').max('now')
});
В данном случае добавляются ограничения диапазона дат, что позволяет контролировать не только формат, но и бизнес-логику временных значений.
При необходимости расширенной логики применяется
.custom():
const schema = Joi.object({
createdAt: Joi.date().iso().custom((value, helpers) => {
if (value.getUTCHours() === 0) {
return helpers.error('date.invalidMidnight');
}
return value;
})
});
Такая конструкция позволяет накладывать дополнительные ограничения на уже валидированный ISO-формат.
При передаче данных через JSON ISO-строки являются стандартом де-факто:
{
"createdAt": "2026-05-10T14:30:00Z"
}
После валидации через Joi.date().iso() значение может
быть преобразовано в Date, что требует внимательности при
последующей сериализации, так как формат может измениться.
ISO-валидация чаще всего применяется в следующих случаях:
Стандартизация через ISO 8601 позволяет избежать проблем локализации и неоднозначности форматов.
При работе с ISO-форматами следует учитывать:
Z или offsetDateЭти аспекты влияют на архитектурные решения при проектировании схем валидации.