# DateSchema _(no submodules)_ ## Purpose `DateSchema` validates that an input is a JavaScript `Date` instance with a valid (non-NaN) time value, and optionally enforces inclusive `min` / `max` date boundaries. It does not coerce ISO strings or timestamps to `Date`; use `coerceDate` from `@suaveplan/validation` for that. The schema is immutable — each constraint builder returns a new `DateSchema`. ## Features - Type check: rejects non-Date values with `VALIDATION.INVALID_TYPE` - Invalid date detection: rejects `new Date("invalid")` with `VALIDATION.DATE.INVALID` - `min(d)` — date must be on or after `d` (inclusive) - `max(d)` — date must be on or before `d` (inclusive) ## Usage: Basic Example ```typescript import { date } from "@suaveplan/validation"; const born = date().max(new Date()); born.parse(new Date("1990-01-01")); // valid born.parse(new Date("2099-01-01")); // throws ValidationError (too late) ``` ## Usage: Advanced Example ```typescript import { date, object } from "@suaveplan/validation"; const booking = object({ checkIn: date().min(new Date()), checkOut: date(), }).refine( (v) => v.checkOut > v.checkIn, "Check-out must be after check-in", ); const result = booking.safeParse({ checkIn: new Date("2025-06-01"), checkOut: new Date("2025-06-07"), }); ``` ## API Reference ### `date(): DateSchema` Returns an unconstrained `DateSchema`. ### `min(d: Date): DateSchema` Returns a new `DateSchema` requiring the input date to be ≥ `d`. Emits `VALIDATION.DATE.TOO_EARLY` on failure. ### `max(d: Date): DateSchema` Returns a new `DateSchema` requiring the input date to be ≤ `d`. Emits `VALIDATION.DATE.TOO_LATE` on failure. ## Implementation Notes - `Date` validity is checked via `Number.isNaN(input.getTime())`, which correctly identifies `new Date("invalid")` without requiring string inspection. - Boundary comparisons use JavaScript `<` / `>` on `Date` objects, which internally compares millisecond timestamps. - String-to-Date coercion is intentionally omitted. Pair with `coerceDate` when accepting JSON payloads. ### Parse Behaviour `z.date()` accepts only `Date` instances; `z.coerce.date()` additionally accepts ISO-8601 strings and millisecond-epoch numbers. Invalid dates (`new Date("nope")` — a `Date` with `NaN` time) are rejected as `invalid_date`. Refinements `min()` / `max()` compare `getTime()` values so time-zone differences fold into the numeric comparison.