JSONからZodスキーマで日付文字列を検証する

JSONから生成されたZodスキーマでISO 8601日付文字列を検証する方法を学びます。z.string().datetime()、z.coerce.date()、カスタム日付パースをカバー。

Validation

詳細な説明

Zodの日付バリデーション

JSONにはネイティブの日付型がありません。日付は文字列として送信されます。Zodは日付文字列を検証・変換するための複数のアプローチを提供します。

JSON例

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

アプローチ1:ISO文字列として検証

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形式
  completedAt: z.string().datetime().nullable(),
});

アプローチ2:Dateオブジェクトに変換

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()はパース中に文字列をDateオブジェクトに変換

アプローチ3:バリデーション付き変換

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(),
});

組み込み日付バリデーター

メソッド 受け入れるフォーマット
.datetime() 時刻付きISO 8601:2024-03-15T10:30:00Z
.date() 日付のみ:2024-03-15
.time() 時刻のみ:10:30:00

タイムゾーンの処理

// UTCオフセットを必須に
z.string().datetime({ offset: true })
// 受理:"2024-03-15T10:30:00+09:00"
// 拒否:"2024-03-15T10:30:00"

// ローカル時刻を許可(オフセットなし)
z.string().datetime({ local: true })
// 受理:"2024-03-15T10:30:00"

// ミリ秒精度
z.string().datetime({ precision: 3 })
// 受理:"2024-03-15T10:30:00.000Z"

推奨事項

バリデーションのみのスキーマ(例:APIレスポンスバリデーション)にはz.string().datetime()を使用し、後続処理でDateオブジェクトが必要な場合はz.coerce.date()または.transform()を使用してください。

ユースケース

複数のAPIから異なるフォーマットのタイムスタンプを受け取り、アプリケーションロジック用にDateオブジェクトに変換する前にISO 8601準拠を検証するZodスキーマが必要な場合に使用します。

試してみる — JSON to Zod Schema

フルツールを開く