Pythonでdatetimeを扱うことも例外ではなく、datetimeを扱うことは難しいことです。
Pythonの組み込みモジュールである datetime
は、 date
, datetime
, time
, timezone
, timedelta
といったいくつかのクラスを導入し、Arrowなどの公式モジュールが抱える問題を解決するためにいくつかの外部ライブラリが生まれました。
このガイドでは、Deloreanでdatetimeオブジェクトを比較する方法を見ていきます。
このライブラリは、タイムゾーンに関する問題を解決するための標準ライブラリであるpytzと、任意の2つのdatetimeオブジェクト間の差分を計算するためのdateutilをベースに構築されています。
Deloreanのインストール 仮想環境の構築
Deloreanは、pip
経由でインストールすることができます。
一般に、仮想環境で作業することは、異なるプロジェクトで必要とされる依存関係を分離して整理することができるため、推奨されます。
LinuxやMacOSで仮想環境を構築するには、以下のようにします。
$ python3 -m venv env
$ source env/bin/activate
$ python3 -m pip install delorean
または、Windowsでは、次のように実行します。
$ virtualenv env
$ .envScriptsctivate
$ python3 -m pip install delorean
Deloreanを用いたタイムゾーンなしのDatetime(Naive Datetime)の比較
まず最初に、タイムゾーンを持たない日付、つまりタイムゾーンの情報を持たず、ある時点の時刻を表す日付を比較してみましょう。
つまり、 Delorean
オブジェクトの timezone
を設定することはできますが、プリントバックされるのは UTC になってしまうのです。
from delorean import Delorean
import datetime
naive_d1 = Delorean(datetime=datetime.datetime(2021, 5, 15), timezone='UTC').naive
naive_d2 = Delorean(datetime=datetime.datetime(2021, 5, 15, 5), timezone='UTC').naive
naive_d3 = Delorean(datetime=datetime.datetime(2021, 5, 15, 5), timezone='US/Central').naive
print("naive_d1 == naive_d2 is", naive_d1 == naive_d2)
print("naive_d2 > naive_d1 is", naive_d2 > naive_d1)
print("naive_d3 == naive_d2 + 5h is", naive_d3 == naive_d2 + datetime.timedelta(hours=5))
この結果は
naive_d1 == naive_d2 is False
naive_d2 > naive_d1 is True
naive_d3 == naive_d2 + 5h is True
naive_d1は
naive_d2` と同じではありません。
なぜなら、こちらの方がより多くの情報を持っているからです – 時刻が定義されており、デフォルト(正午)ではないからです。
このため、naive_d2
は naive_d1
よりも後の時点にあり、「より偉大」な存在となります。
また、 naive_d3
は naive_d2
と異なるタイムゾーンにありますが、これは naive_d2
に 5 時間の timedelta
を追加して、両者が等しいことを示す True
を返せば簡単に修正することができます。
もし、 naive_d2
と naive_d3
が両方とも午前5時に設定されているにもかかわらず、 naive_d2
と naive_d3
をプリントアウトしてしまったとしたら。
print(naive_d2)
print(naive_d3)
どちらも UTC にマッチしているので、シフトした結果が得られます。
2021-05-15 05:00:00
2021-05-15 10:00:00
Deloreanを用いたDatetimeとTimezoneの比較(Aware Datetime)#### Deloreanを用いたDatetimeとTimezoneの比較(Aware Datetime
タイムゾーンを考慮した日付は、単一のタイムゾーンにマッチしません。
もし、2つの異なるタイムゾーンで同じ時刻を示す2つの日付を作成したとします。
d1 = Delorean(datetime=datetime.datetime(2021, 5, 15, 5), timezone='UTC')
d2 = Delorean(datetime=datetime.datetime(2021, 5, 15, 5), timezone='Africa/Lagos')
この2つの日付を印刷すると、両方とも午前5時を表しますが、タイムゾーンは異なります。
print(d2)
print(d3)
この結果、次のようになります。
Delorean(datetime=datetime.datetime(2021, 5, 15, 5, 0), timezone='UTC')
Delorean(datetime=datetime.datetime(2021, 5, 15, 5, 0), timezone='Africa/Lagos')
この場合、単純な日付の比較とは少し違ってきます。
これらは両方とも同じ時計の時刻を表していますが、同じ時点ではありません。
Deloreanは、2つの Delorean
オブジェクトが同じ時刻を表しているかどうかを比較します。
タイムゾーンのある日付に時間を足して一致させることはできますが。
アフリカ/ラゴスのタイムゾーンは
UTC`より1時間遅れているだけなので、1時間追加すれば同じ時点を示すことになります。
from delorean import Delorean
import datetime
d1 = Delorean(datetime=datetime.datetime(2021, 5, 15), timezone='UTC')
d2 = Delorean(datetime=datetime.datetime(2021, 5, 15, 5), timezone='UTC')
d3 = Delorean(datetime=datetime.datetime(2021, 5, 15, 5), timezone='Africa/Lagos')
print("d2 == d3 +1h is", d2 == d3 + datetime.timedelta(hours=1))
print("d1 > d3 -", d1 > d3)
さらに、d1
は時間に関するデータを持っていないので、正午に設定されています。
d1が
UTCに属していても、
d3` の 4 時間前になります。
d2 == d3 +1h is True
d1 > d3 - False
結論
このガイドでは、Deloreanでタイムゾーンを無視した日付とタイムゾーンを考慮した日付を比較する方法について見てきました。