Docs Menu

Docs Homeアプリケーションの開発Python ドライバーPyMongo

日付と時刻

項目一覧

  • Overview
  • 用語
  • ネイティブ日時
  • 認識済み日時
  • ローカライズ
  • 日時の読み取り
  • ネイティブ UTC 日時
  • 認識済み UTC 日時
  • ローカライズされた日時
  • 日時の保存
  • 範囲外の日時の処理
  • DatetimeConversion.DATETIME
  • DatetimeConversion.DATETIME_MS
  • DatetimeConversion.DATETIME_Auto
  • DatetimeConversion.DATETIME_CLAMP
  • API ドキュメント

このガイドでは、PyMongo で Python datetimeオブジェクトを処理する方法を学習できます。

Python は日付と時刻を表すために専用のデータ型datetime.datetimeを使用します。 MongoDB は、英国ロード フィールドを対象としたグローバル タイム標準(UTC)datetime値を保存します。

UTC オフセットやタイムゾーンに関する追加情報が含まれていない場合、 datetime値はネイティブではありません。 以下は、ネイティブのdatetimeオブジェクトの例です。

datetime(2002, 10, 27, 14, 0, 0)

datetime値は、 tzinfo属性が含まれている場合に認識されます。 この属性は、UTC 時間からの値のオフセット、そのタイムゾーン、夏時間が有効になっているかどうかを示します。 以下は、認識されているdatetimeオブジェクトの例です。

datetime(2002, 10, 27, 6, 0,
tzinfo=<DstTzInfo 'US/Pacific' PST-1 day, 16:00:00 STD>)

ローカライズとは、 datetimeの値に時間を追加したり、その値から時間を減算してその値を別のタイムゾーンに変換するプロセスです。 datetime値をローカライズするには、次の手順を実行します。

  1. pip を使用して、Python 環境にpytzライブラリをインストールします。 pip install pytz

  2. pytz.timezoneオブジェクトを作成します。 ターゲット タイム ゾーンを string としてコンストラクターに渡します。

  3. ローカライズするためのdatetime値を渡して、 timezoneオブジェクトでlocalize()メソッドを呼び出します。

次のコード例では、 datetime値を"US/Pacific"タイムゾーン(8 時間のオフセット)にローカライズします。

from datetime import datetime
from pytz import timezone
utc_datetime = datetime(2002, 10, 27, 6, 0, 0)
pacific = timezone("US/Pacific")
local_datetime = pacific.localize(utc_datetime)
print(f"UTC datetime: {utc_datetime}")
print(f"Local datetime: {local_datetime}")
UTC datetime: 2002-10-27 06:00:00
Local datetime: 2002-10-27 06:00:00-08:00

タイムゾーン文字列の標準リストについては、 タイムゾーン データベース を参照してください または Wikipedia 上の対応する記事。

重要

PyMongo では、時刻のない日付の BSON 型がないため、 datetime.dateインスタンスを保存できません。 MongoDB に保存する前に、すべてのdateオブジェクトをdatetimeオブジェクトに変換します。

PyMongo を使用してdatetime値を取得する場合、ドライバーはネイティブ UTC、認識済み UTC、またはローカライズされた値としてそれを形式できます。 次のセクションでは、各種類の値を取得する方法について説明します。

これらのセクションでは、 sample_collectionという名前の MongoDB コレクションに次のドキュメントが含まれていることを前提としています。 "date"フィールドの値は UTC datetime値です。

{"date": datetime(2002, 10, 27, 14, 0, 0)}

デフォルトでは、PyMongo は追加情報のない UTC datetime値を検索します。 次のコード例では、サンプル ドキュメントを取得し、 datetime値を出力します。 出力される値は、サンプルドキュメントの と同じです。

from datetime import datetime
collection = database["sample_collection"]
find_result = collection.find_one()["date"]
print(f"datetime: {find_result}")
print(f"datetime.tzinfo: {find_result.tzinfo}")

PyMongo に認識済みのdatetime値を取得するよう指示するには、 CodecOptionsオブジェクトを作成し、 tz_aware = Trueをコンストラクターに渡します。 次に、 CodecOptionsオブジェクトをget_collection()メソッドに渡します。

次のコード例では、サンプル ドキュメントからdatetimeの値を認識済みのdatetimeとして取得します。

from pymongo import MongoClient
from datetime import datetime
from bson.codec_options import CodecOptions
options = CodecOptions(tz_aware = True)
collection = database.get_collection("sample_collection", options)
find_result = collection.find_one()["date"]
print(f"datetime: {find_result}")
print(f"datetime.tzinfo: {find_result.tzinfo}")

ユーザーにdatetime値を表示する予定の場合は、MongoDB から読み取られたすべての時間を特定のタイムゾーンに自動的に変換するように PyMongo に指示できます。 そのためには、「用語」セクションで説明されているように、ターゲット タイムゾーン用のtimezoneオブジェクトを作成します。 Then, create a CodecOptions object and pass the following arguments to the constructor:

  • tz_aware: Trueに設定します。

  • tzinfo: timezoneオブジェクト。

次のコード例では、サンプルドキュメントを取得していますが、 tz_awaretzinfo引数を使用してdatetimeの値を"US/Pacific"タイムゾーンに自動的にローカライズします。

from pymongo import MongoClient
from datetime import datetime
from bson.codec_options import CodecOptions
import pytz
from pytz import timezone
pacific = timezone("US/Pacific")
options = CodecOptions(tz_aware = True, tzinfo = pacific)
collection = database.get_collection("sample_collection", options)
find_result = collection.find_one()["date"]
print(f"datetime: {find_result}")
print(f"datetime.tzinfo: {find_result.tzinfo}")

Tip

上記の例では、コレクション レベルでコーデック オプションを指定しています。 クライアント レベルまたはデータベース レベルでコーデック オプションを指定することもできます。

整合性のために、UTC datetime値のみを MongoDB に保存します。 PyMongo を使用してdatetime値を含むフィールドを作成または更新すると、ドライバーは最初にdatetime値がネイティブか認識されているかを確認します。

  • datetimeがネイティブの場合、PyMongo はdatetimeが UTC であると想定し、それを変更せずに MongoDB に保存します。

  • datetimeが認識されている場合、PyMongo は MongoDB に保存する前に時間を自動的に UTC に変換します。

次のコード例では、 "US/Pacific"タイムゾーンにローカライズされたdatetime値を含むドキュメントを挿入します。 PyMongo は、付属のタイムゾーンを使用してローカル時間を UTC に変換します。 ドキュメントが MongoDB から取得された場合、 datetime値は UTC です。

from pymongo import MongoClient
from datetime import datetime
from pytz import timezone
utc_datetime = datetime(2002, 10, 27, 6, 0, 0)
pacific = timezone("US/Pacific")
local_datetime = pacific.localize(utc_datetime)
print(f"datetime before storage: {local_datetime}")
collection.insert_one({"date": local_datetime})
find_result = collection.find_one()["date"]
print(f"datetime after storage: {find_result}")

重要

datetime.now()

引数なしでdatetime.now()メソッドを呼び出すのは避けてください。 これにより、現在のローカル時間が返されます。

代わりに、UTC で現在時刻を返すdatetime.now(tz=datetime.timezone.utc)メソッドを常に呼び出します。

Python のdatetimeクラスは、 datetime.minからdatetime.maxまでのdatetime値のみを表すことができます( 1 - 9999年)。 BSON を使用すると、はるかに大きな日付と時刻の範囲を表すことができます。これにより、64 Unix エポック からの任意の ビット ミリ秒値が利用できます。

PyMongo で BSON 時間を表すには、Python の組み込みint型のラッパーであるdatetime_ms.DatetimeMSオブジェクトを作成します。 次のいずれかの値を渡すことで、 DatetimeMSオブジェクトを手動で作成できます。

  • UNIX エポックからのミリ秒数を表すint

  • datetimeオブジェクト

次のコード例では、年 - 146136543 ( datetimeの範囲外の日付)を表すint値を渡してDatetimeMSオブジェクトを構築します。

from bson.datetime_ms import DatetimeMS
out_of_range = DatetimeMS(-(2**62))

また、UTC datetime値をDatetimeMSオブジェクトとして自動的にデコードするように PyMongo に指示することもできます。 そのためには、 CodecOptionsdatetime_conversionパラメータをdatetime_ms.DatetimeConversion列挙型の値に設定します。 次のセクションでは、これらの値について説明します。

Tip

DatetimeMS オブジェクトは、 DatetimeMSの他のインスタンスに対する豊富な比較メソッドをサポートします。 また、 DatetimeMS.to_datetime()メソッドを使用してこれらをdatetimeオブジェクトに変換することもできます。

DatetimeConversion.DATETIME は、デフォルト値です。 この値により、次の例に示すように、PyMongo は範囲外の日付をデコードしようとするとエラーを発生させます。

from datetime import datetime
from bson import encode, decode
from bson.datetime_ms import DatetimeMS
out_of_range = DatetimeMS(-(2**62))
val = encode({"date": out_of_range})
decoded = decode(val)
print(decoded)
...
bson.errors.InvalidBSON: year -146136543 is out of range (Consider Using
CodecOptions(datetime_conversion=DATETIME_AUTO) or
MongoClient(datetime_conversion='DATETIME_AUTO')).
...

この値は、日付がdatetimeの範囲内であっても、 DatetimeMSオブジェクトのみを返すように PyMongo に指示します。

from datetime import datetime
from bson import encode, decode
from bson.datetime_ms import DatetimeMS
from bson.codec_options import CodecOptions, DatetimeConversion
val = encode({"date": datetime(1970, 1, 2)})
codec_ms = CodecOptions(datetime_conversion=DatetimeConversion.DATETIME_MS)
decoded = decode(val, codec_options=codec_ms)
print(decoded)
{"date": DatetimeMS(86400000)}

この値は、値がdatetimeの範囲内にある場合はdatetimeオブジェクトを返し、それ以外の場合はDatetimeMSオブジェクトを返すように PyMongo に指示します。 次のコード例では、 datetime範囲内の 1 つの日時と範囲外の日時をエンコードおよびデコードします。

from datetime import datetime
from bson import encode, decode
from bson.datetime_ms import DatetimeMS
from bson.codec_options import CodecOptions, DatetimeConversion
in_range = encode({"date": datetime(1970, 1, 1)})
out_of_range = encode({"date": DatetimeMS(-(2**62))})
codec_auto = CodecOptions(datetime_conversion=DatetimeConversion.DATETIME_AUTO)
in_decoded = decode(in_range, codec_options=codec_auto)
out_decoded = decode(out_of_range, codec_options=codec_auto)
print(f"in-range date: {in_decoded}")
print(f"out-of-range date: {out_decoded}")
in-range date: {"date": datetime.datetime(1970, 1, 1, 0, 0)}
out-of-range date: {'x': DatetimeMS(-4611686018427387904)}

この値は結果のdatetimeオブジェクトを「ロック」し、それらをdatetimeの範囲( 999 、 000マイクロ秒に削除)内に収まるようにします。

次のコード例では、 datetime範囲より前の 1 つの日時とdatetime範囲より後の 1 つの日時をエンコードおよびデコードします。 結果の値は、許可された範囲の先頭と末尾にあります。

from datetime import datetime
from bson import encode, decode
from bson.datetime_ms import DatetimeMS
from bson.codec_options import CodecOptions, DatetimeConversion
before = encode({"date": DatetimeMS(-(2**62))})
after = encode({"date": DatetimeMS(2**62)})
codec_clamp = CodecOptions(datetime_conversion=DatetimeConversion.DATETIME_CLAMP)
before_decoded = decode(before, codec_options=codec_clamp)
after_decoded = decode(after, codec_options=codec_clamp)
print(f"datetime before the range: {before_decoded}")
print(f"datetime after the range: {after_decoded}")
datetime before the range: {"date": datetime.datetime(1, 1, 1, 0, 0)}
datetime after the range: {"date": datetime.datetime(9999, 12, 31, 23, 59, 59, 999000)}

PyMongo での日付と時刻の操作の詳細については、次の API ドキュメントを参照してください。

← カスタム タイプ