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クライアントを構築している場合に使用します。