Сравниваем дату и время с помощью 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.

Ответить