PythonでDeloreanとDatetimeを比較する – タイムゾーンがあるときとないとき

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_d1naive_d2` と同じではありません。

なぜなら、こちらの方がより多くの情報を持っているからです – 時刻が定義されており、デフォルト(正午)ではないからです。

このため、naive_d2naive_d1 よりも後の時点にあり、「より偉大」な存在となります。

また、 naive_d3naive_d2 と異なるタイムゾーンにありますが、これは naive_d2 に 5 時間の timedelta を追加して、両者が等しいことを示す True を返せば簡単に修正することができます。

もし、 naive_d2naive_d3 が両方とも午前5時に設定されているにもかかわらず、 naive_d2naive_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は時間に関するデータを持っていないので、正午に設定されています。

d1UTCに属していても、d3` の 4 時間前になります。

d2 == d3 +1h is True
d1 > d3 - False


結論

このガイドでは、Deloreanでタイムゾーンを無視した日付とタイムゾーンを考慮した日付を比較する方法について見てきました。

タイトルとURLをコピーしました