Validate Date Strings in Zod Schemas from JSON

Learn how to validate ISO 8601 date strings in Zod schemas generated from JSON. Covers z.string().datetime(), z.coerce.date(), and custom date parsing.

Validation

Detailed Explanation

Date Validation in Zod

JSON has no native date type — dates are transmitted as strings. Zod provides several approaches to validate and transform date strings.

Example JSON

{
  "id": 1,
  "title": "Launch v2",
  "createdAt": "2024-03-15T10:30:00Z",
  "dueDate": "2024-04-01",
  "completedAt": null
}

Approach 1: Validate as ISO String

import { z } from "zod";

const taskSchema = z.object({
  id: z.number(),
  title: z.string(),
  createdAt: z.string().datetime(),
  dueDate: z.string().date(),         // YYYY-MM-DD format
  completedAt: z.string().datetime().nullable(),
});

Approach 2: Coerce to Date Object

const taskSchema = z.object({
  id: z.number(),
  title: z.string(),
  createdAt: z.coerce.date(),
  dueDate: z.coerce.date(),
  completedAt: z.coerce.date().nullable(),
});

// z.coerce.date() converts strings to Date objects during parsing

Approach 3: Transform with Validation

const isoDateString = z.string()
  .datetime()
  .transform((s) => new Date(s));

const taskSchema = z.object({
  id: z.number(),
  title: z.string(),
  createdAt: isoDateString,
  dueDate: z.string().date().transform((s) => new Date(s)),
  completedAt: isoDateString.nullable(),
});

Built-in Date Validators

Method Format accepted
.datetime() ISO 8601 with time: 2024-03-15T10:30:00Z
.date() Date only: 2024-03-15
.time() Time only: 10:30:00

Timezone Handling

// Require UTC offset
z.string().datetime({ offset: true })
// Accepts: "2024-03-15T10:30:00+09:00"
// Rejects: "2024-03-15T10:30:00"

// Allow local time (no offset)
z.string().datetime({ local: true })
// Accepts: "2024-03-15T10:30:00"

// Millisecond precision
z.string().datetime({ precision: 3 })
// Accepts: "2024-03-15T10:30:00.000Z"

Recommendation

Use z.string().datetime() for validation-only schemas (e.g., API response validation) and z.coerce.date() or .transform() when you need Date objects for date arithmetic downstream.

Use Case

You receive timestamps from multiple APIs in different formats and need a Zod schema that validates ISO 8601 compliance before transforming strings into Date objects for your application logic.

Try It — JSON to Zod Schema

Open full tool