PythonでのJSON日付文字列とdatetimeの処理

JSON ISO 8601日付文字列をPython datetimeオブジェクトに変換する方法を学びます。パース、タイムゾーン処理、dataclassやPydanticとの統合を解説します。

Advanced Patterns

詳細な説明

JSON日付からPython datetimeへ

JSONにはネイティブの日付型がありません。日付は文字列として送信され、通常はISO 8601形式です。Pythonの datetime モジュールが適切な日付/時刻処理を提供します。

JSONの例

{
  "id": 42,
  "title": "Deploy v2.0",
  "created_at": "2024-06-15T09:30:00Z",
  "updated_at": "2024-06-15T14:22:33+09:00",
  "due_date": "2024-07-01"
}

生成されるPython(dataclass)

from dataclasses import dataclass
from datetime import datetime, date

@dataclass
class Task:
    id: int
    title: str
    created_at: datetime
    updated_at: datetime
    due_date: date

ISO 8601文字列のパース

from datetime import datetime, date

# タイムゾーン付き完全なdatetime
dt = datetime.fromisoformat("2024-06-15T09:30:00Z")
# Python 3.11+: "Z"サフィックスを処理
# Python 3.11未満: "Z"を"+00:00"に置換

# 日付のみ
d = date.fromisoformat("2024-07-01")

後処理によるデシリアライゼーション

json.loads() は文字列を返し、datetimeオブジェクトは返しません。変換ステップが必要です:

import json

data = json.loads(raw_json)
task = Task(
    id=data["id"],
    title=data["title"],
    created_at=datetime.fromisoformat(data["created_at"]),
    updated_at=datetime.fromisoformat(data["updated_at"]),
    due_date=date.fromisoformat(data["due_date"]),
)

Pydanticの場合(自動)

Pydanticはdatetimeのパースを自動的に処理します:

from pydantic import BaseModel
from datetime import datetime, date

class Task(BaseModel):
    id: int
    title: str
    created_at: datetime
    updated_at: datetime
    due_date: date

task = Task.model_validate_json(raw_json)
# created_atはすでにdatetimeオブジェクト!

タイムゾーンの認識

常にタイムゾーン対応のdatetimeを使用してください:

from datetime import timezone

utc_now = datetime.now(timezone.utc)

Nullableなタイムスタンプ

nullになりうるフィールド(例:deleted_at)の場合:

from typing import Optional
from datetime import datetime

deleted_at: Optional[datetime] = None

ユースケース

ISO 8601タイムスタンプをパースし、期間を計算し、デッドラインを比較し、ローカルタイムゾーンで日付を表示する必要があるタスク管理APIクライアントを構築している場合に使用します。

試してみる — JSON to Python Converter

フルツールを開く