Работа с датами в схемах Zod опирается на строгую типизацию объекта
Date и его корректную валидацию через встроенный примитив
z.date().
Схема z.date() принимает только валидные экземпляры
Date.
import { z } from "zod";
const schema = z.date();
schema.parse(new Date()); // корректно
schema.parse("2024-01-01"); // ошибка
schema.parse(Date.now()); // ошибка
Ключевое поведение:
DateInvalid Date)schema.parse(new Date("invalid")); // ошибка: Invalid Date
Объект Date в JavaScript может существовать в невалидном
состоянии:
new Date("not-a-date") // Invalid Date
Zod дополнительно проверяет корректность:
const schema = z.date();
schema.parse(new Date("not-a-date"));
// ошибка валидации
Таким образом, недостаточно только типа Date, важна его
семантическая корректность.
Во многих входных данных даты приходят в виде строк или timestamp.
Для этого используется z.coerce.date().
const schema = z.coerce.date();
schema.parse("2024-01-01"); // Date
schema.parse(1704067200000); // Date
Поддерживаемые форматы:
Date.parseОсобенность:
Zod предоставляет встроенные методы ограничения диапазона:
const schema = z.date().min(new Date("2020-01-01"));
const schema = z.date().max(new Date("2030-01-01"));
Комбинирование:
const schema = z.date().min(new Date("2020-01-01")).max(new Date("2030-01-01"));
Поведение:
Для нестандартных условий применяется refine.
const schema = z.date().refine((date) => {
const year = date.getFullYear();
return year % 4 === 0;
}, {
message: "Год должен быть високосным"
});
Типичные сценарии:
const schema = z.date().optional();
Допустимые значения:
const schema = z.date().nullable();
Допустимые значения:
const schema = z.date().optional().nullable();
Zod позволяет трансформировать дату в другой формат.
const schema = z.date().transform((date) => date.toISOString());
Результат:
Частые преобразования:
const schema = z.date().transform((d) => ({
year: d.getFullYear(),
month: d.getMonth() + 1,
day: d.getDate()
}));
Без coerce строка всегда считается ошибкой:
z.date().parse("2024-01-01"); // ошибка
Корректная обработка:
z.coerce.date().parse("2024-01-01"); // Date
Метод safeParse позволяет получить результат без
исключений.
const result = z.date().safeParse("invalid");
if (!result.success) {
console.log(result.error);
}
Структура ошибки включает:
Числовые значения интерпретируются только через coercion:
z.coerce.date().parse(0); // 1970-01-01
Без coercion:
z.date().parse(0); // ошибка
JavaScript Date всегда хранит время в UTC-формате, но
отображение зависит от локали.
const schema = z.coerce.date();
schema.parse("2024-01-01T10:00:00Z");
Особенности:
z.date().parse("2024-01-01");
z.date().parse(new Date("bad"));
z.date().parse(1700000000000);
const schema = z.object({
createdAt: z.coerce.date(),
updatedAt: z.coerce.date().optional()
});
const schema = z.array(z.coerce.date());
const schema = z.union([
z.date(),
z.string().transform((v) => new Date(v))
]);
Частый сценарий — получение даты из JSON:
{
"createdAt": "2024-01-01T12:00:00Z"
}
Схема:
const schema = z.object({
createdAt: z.coerce.date()
});
Поведение:
const schema = z.date().refine((date) => {
return date <= new Date();
}, {
message: "Дата не может быть в будущем"
});
const schema = z.date().refine((date) => {
const day = date.getDay();
return day !== 0 && day !== 6;
});
При передаче данных через API часто требуется обратное преобразование:
const schema = z.date().transform((d) => d.toISOString());
Это обеспечивает: