Last Updated: 3/12/2026
Dates
Use z.date() to validate Date instances.
Basic Date Validation
import * as z from "zod";
const dateSchema = z.date();
dateSchema.parse(new Date()); // ✅ success
dateSchema.parse("2022-01-12T06:15:00.000Z"); // ❌ throws (strings are not Date objects)Custom Error Messages
To customize the error message:
const dateSchema = z.date({
error: issue => issue.input === undefined ? "Required" : "Invalid date"
});Date Validations
Zod provides a handful of date-specific validations:
// Minimum date
z.date().min(new Date("1900-01-01"), { error: "Too old!" });
// Maximum date
z.date().max(new Date(), { error: "Too young!" });
// Both constraints
const birthdateSchema = z.date()
.min(new Date("1900-01-01"))
.max(new Date());Working with Date Strings
If you’re receiving date strings (common in APIs), you’ll need to convert them to Date objects. Zod provides several ISO format validators for strings:
ISO DateTime Strings
const datetime = z.iso.datetime();
datetime.parse("2020-01-01T06:15:00Z"); // ✅
datetime.parse("2020-01-01T06:15:00.123Z"); // ✅
datetime.parse("2020-01-01T06:15:00.123456Z"); // ✅ (arbitrary precision)
datetime.parse("2020-01-01T06:15:00+02:00"); // ❌ (offsets not allowed by default)
datetime.parse("2020-01-01T06:15:00"); // ❌ (local not allowed by default)Allowing Timezone Offsets
const datetime = z.iso.datetime({ offset: true });
datetime.parse("2020-01-01T06:15:00+02:00"); // ✅
datetime.parse("2020-01-01T06:15:00Z"); // ✅ (Z is still supported)Allowing Local (Unqualified) Datetimes
const schema = z.iso.datetime({ local: true });
schema.parse("2020-01-01T06:15:01"); // ✅
schema.parse("2020-01-01T06:15"); // ✅ (seconds optional)Precision Constraints
// Default: seconds optional, arbitrary sub-second precision allowed
const a = z.iso.datetime();
a.parse("2020-01-01T06:15Z"); // ✅
a.parse("2020-01-01T06:15:00Z"); // ✅
a.parse("2020-01-01T06:15:00.123Z"); // ✅
// Minute precision (no seconds)
const b = z.iso.datetime({ precision: -1 });
b.parse("2020-01-01T06:15Z"); // ✅
b.parse("2020-01-01T06:15:00Z"); // ❌
// Second precision only
const c = z.iso.datetime({ precision: 0 });
c.parse("2020-01-01T06:15:00Z"); // ✅
c.parse("2020-01-01T06:15:00.123Z"); // ❌
// Millisecond precision only
const d = z.iso.datetime({ precision: 3 });
d.parse("2020-01-01T06:15:00.123Z"); // ✅ISO Date Strings
The z.iso.date() method validates strings in the format YYYY-MM-DD:
const date = z.iso.date();
date.parse("2020-01-01"); // ✅
date.parse("2020-1-1"); // ❌ (must be zero-padded)
date.parse("2020-01-32"); // ❌ (invalid day)ISO Time Strings
The z.iso.time() method validates strings in the format HH:MM[:SS[.s+]]:
const time = z.iso.time();
time.parse("03:15"); // ✅
time.parse("03:15:00"); // ✅
time.parse("03:15:00.9999999"); // ✅ (arbitrary precision)
time.parse("03:15:00Z"); // ❌ (no Z allowed)
time.parse("03:15:00+02:00"); // ❌ (no offsets allowed)Converting Strings to Dates
To parse ISO datetime strings and convert them to Date objects, use a codec or transform:
// Using transform
const stringToDate = z.string()
.datetime()
.transform(val => new Date(val));
stringToDate.parse("2020-01-01T06:15:00Z"); // => Date object
// Using codec (Zod 4.1+)
const isoDatetimeToDate = z.codec(
z.iso.datetime(),
z.date(),
{
decode: (isoString) => new Date(isoString),
encode: (date) => date.toISOString()
}
);Common Use Cases
Birthdate Validation
const birthdateSchema = z.date()
.min(new Date("1900-01-01"), "Birthdate too far in the past")
.max(new Date(), "Birthdate cannot be in the future");Event Date Range
const eventSchema = z.object({
startDate: z.date(),
endDate: z.date()
}).refine(data => data.endDate > data.startDate, {
message: "End date must be after start date",
path: ["endDate"]
});API Timestamp Parsing
const apiResponseSchema = z.object({
createdAt: z.string().datetime().transform(val => new Date(val)),
updatedAt: z.string().datetime().transform(val => new Date(val))
});Best Practices
- Use
z.date()for validatingDateinstances - Use
z.iso.datetime()for validating ISO datetime strings - Use transforms or codecs to convert strings to
Dateobjects - Add min/max constraints to ensure dates are within acceptable ranges
- Use refinements for complex date logic (e.g., end date after start date)