0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Python】datetimeオブジェクトはそのままじゃJSON化できない

Posted at

パイソニスタの皆さん、こんにちは!:snake:

FastAPIでAPIエンドポイントを実装していたところ、

TypeError: Object of type datetime is not JSON serializable

というエラーに出会いましたので、こちらの解説と回避策をご紹介します。

何をしたら起きたの?

ある日の業務で、FastAPIライブラリを使って次のコードを実装していました。

from fastapi import FastAPI
from fastapi.responses import JSONResponse
from datetime import datetime

app = FastAPI()

@app.get("/")
def main_endpoint():

    # 実際はデータベースから取得したタイムスタンプデータです。
    datetime_data = datetime(2025, 9, 20, 15, 45, 30)

    response_dict = {"timestamp": datetime_data}

    return JSONResponse(content=response_dict)

実際のコードとは異なりますが、得られる挙動は同じです。

ここで、uvicorn君を起動してエンドポイントにアクセスすると、以下のエラーが表示されました。

TypeError: Object of type datetime is not JSON serializable

datetime型のオブジェクトはJSONシリアライズできません

どうやら、datetimeオブジェクトが原因でFastAPIのJSONResponse関数実行中にエラーが起きたようです。

どうやって直したの?

調べたところ、Python標準のJSONエンコーダはdatetime型をそのまま扱えないことが分かりました。
そこで、datetimeオブジェクトを文字列に変換して対応しました。

[方法1] str関数で文字列化する

標準関数のstr()でdatetimeオブジェクトを囲むと、文字列に変換できます。

from datetime import datetime

datetime_data = datetime(2025, 9, 20, 15, 45, 30)
response_dict = {"timestamp": str(datetime_data)} # datetimeを文字列化

[方法2] FastAPIのシリアライズ関数でJSON化する

FastAPIには、datetimeオブジェクトをISO 8601形式の文字列に変換した上でJSONにシリアライズする「jsonable_encoder関数」があります。
これを使うと、datetimeオブジェクトを直接触らなくてもシリアライズできます。

from fastapi.encoders import jsonable_encoder
from datetime import datetime

datetime_data = datetime(2025, 9, 20, 15, 45, 30)
response_dict = {"timestamp": datetime_data} # datetime_dataはdatetimeオブジェクト

return JSONResponse(content=jsonable_encoder(response_dict)) # datetimeを文字列化してJSONシリアライズ

なんでJSON化できないの?

さて、今回のエラーの原因となったJSONですが、なぜdatetimeオブジェクトを格納できないのでしょうか。

JSONは、IETFが発行する標準文書「RFC (Request for Comments)」によって定義されています。
JSONについて規定したRFC 8259を参照すると、次の通り定義されています。

JavaScript Object Notation (JSON) is a text format for the serialization of structured data. It is derived from the object literals of JavaScript, as defined in the ECMAScript Programming Language Standard, Third Edition [ECMA-262].

JSON can represent four primitive types (strings, numbers, booleans,and null) and two structured types (objects and arrays).

(1.introductionより引用)

(筆者訳)
JavaScript Object Notation(JSON)は、構造化データをシリアライズするためのテキスト形式である。これは、ECMAScriptプログラミング言語標準 第3版 [ECMA-262] で定義されている JavaScript のオブジェクトリテラルから派生している。

JSONは、4つのプリミティブ型(文字列、数値、真偽値、null)と、2つの構造化型(オブジェクトと配列)を表現できる。

つまり、JSONは

  • 文字列
  • 数値
  • 真偽値 (True, False)
  • null

を格納する配列とオブジェクト(キーと値のペア)しか表現できません。
したがって、datetimeやUUIDのような専用オブジェクトは仕様上そのまま表現できず、文字列などの対応可能な型に変換してから格納する必要があります
今回のエラーはこれが原因で発生したわけです。

(参照) シリアライズ

(参照) オブジェクト

以上です!
最後までお読みいただき、ありがとうございました!

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?