Сравниваем дату и время с помощью Delorean в Python
Вступление
Работать с датой и временем может быть сложно. Обрабатывать дату и время в Python тоже сложно. Встроенный в Ptyhon модуль datetime познакомил нас с несколькими классами: date, datetime, time, timezone и timedelta, а также с несколькими внешними библиотеками, созданными для решения проблем, присутствующих в официальном модуле. Например, Arrow.
В этом гайде мы рассмотрим, как сравнивать объекты даты и времени в Delorean, библиотеке, построенной на базе pytz, которую используют для решения проблем, связанных с часовыми поясами, и dateutil, которая используется для вычисления дельт между любыми 2 заданными объектами даты и времени.
Установка Delorean. Настройка виртуальной среды
Delorean можно установить через pip. Рекомендуется работать в виртуальной среде, поскольку так можно организовать зависимости, необходимые для различных изолированных проектов.
В Linux или MacOS для создания виртуальной среды мы бы запустили:
$ python3 -m venv env
$ source env/bin/activate
$ python3 -m pip install delorean
В Windows запустим:
$ virtualenv env
$ .\env\Scripts\activate
$ python3 -m pip install delorean
Сравниваем дату и временя без учёта часового пояса (наивное время) с помощью Delorean
Сравним наивное время – время, которые не содержит информации о часовом поясе, но представляет определенный момент времени. При этом – вы можете установить timezone объекта Delorean, но при обратной печати он будет в 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 часов, чтобы оно соответствовало naive_d3, и равенство примет значение True.
Если вы хотите вывести naive_d2 и naive_d3, получилось бы следующее (даже если бы они оба были установлены на 5 утра):
print(naive_d2)
print(naive_d3)
Вы получите смещенный результат, так как они оба соответствуют UTC:
2021-05-15 05:00:00
2021-05-15 10:00:00
Сравниваем дату и временя, учитывая часовой пояс с помощью Delorean
Даты с учетом часового пояса не совпадают ни с одним часовым поясом. Если бы вы назначили две даты, обозначив одно и то же время по часам в двух разных часовых поясах, получилось бы следующее:
d1 = Delorean(datetime=datetime.datetime(2021, 5, 15, 5), timezone='UTC')
d2 = Delorean(datetime=datetime.datetime(2021, 5, 15, 5), timezone='Africa/Lagos')
Если бы вы вывели их, они оба обозначали бы 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')
Поэтому сравнение отличается от наивных дат: d2 равно d3 в этом случае? Они оба обозначают одно и то же время по часам, но не один и тот же момент времени. Delorean будет сравнивать, обозначают ли два объекта Delorean один и тот же момент времени, чтобы они не были одинаковыми в глазах библиотеки.
Однако вы можете привязать время к датам часового пояса, чтобы они им соответствовали. Часовой пояс Africa/Lagos отстает от UTC всего на час, поэтому, если мы добавим к нему час, они будут обозначать один и тот же момент времени:
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.