Сравнение дат и времени в Python - с часовыми поясами и без них

Введение При работе с датами часто бывает необходимо знать, наступает ли данная дата до или после другой даты. Мы можем получить эти ответы, сравнив даты. В этой статье мы узнаем, как использовать модуль Python datetime для создания и сравнения как простых (без информации о часовом поясе), так и известных (с информацией о часовом поясе) дат. Для сравнения дат мы будем использовать операторы сравнения в Python: <,>, ==, <=,> =,! =. Примечание. В модуле datetime есть два метода создания объекта даты - d

Вступление

Часто при работе с датами вам нужно знать, наступает ли данная дата до или после другой даты. Мы можем получить эти ответы, сравнив даты.

В этой статье мы узнаем, как использовать datetime для создания и сравнения как простых (без информации о часовом поясе), так и известных (с информацией о часовом поясе) дат.

Для сравнения дат мы будем использовать операторы сравнения в Python: <, >, ==, <=, >=, != .

Примечание. В datetime есть два метода создания объекта даты - datetime.datetime и datetime.date . Сравнение может производиться только с объектами, созданными из одного и того же класса:

 datetime.datetime.now() >= datetime.date.today() 

Это приведет к TypeError :

 TypeError: can't compare datetime.datetime to datetime.date 

Сравнение наивных дат и времени по часовому поясу

Начнем со сравнения наивных дат , которые не имеют информации о часовом поясе. Во-первых, мы хотим импортировать модуль datetime

 from datetime import datetime, date 

Затем давайте сделаем несколько дат, которые мы сможем сравнить:

 date1 = date(1995, 3, 20) 
 date2 = date(2020, 1, 1) 
 dob_a = datetime(1995, 3, 20) 
 dob_b = datetime(2020, 1, 1) 

Сравнить эти объекты так же просто, как сравнить, скажем, целые числа. Дата меньше другой, если ее время предшествует другому.

В нашем случае date1 считается меньше ( < ), чем date2 потому что оно находится дальше во времени:

 print("date1 comes before date2?", date1 < date2) 
 print("date1 comes after date2?", date1 > date2) 
 print("date1 is equal to date2?", date1 == date2) 

Это приводит к:

 date1 comes before date2? True 
 date1 comes after date2? False 
 date1 is equal to date2? False 

Теперь вы обычно включаете эту логику в некоторые операторы управления потоком:

 if dob_a > dob_b: 
 print("person a is older than person b") 
 else: 
 print("person b is older than person a") 

Это приводит к:

 person b is older than person a 

Сравнение дат и времени с учетом часового пояса

Часовые пояса могут немного усложнить ситуацию, хотя, к счастью, мы можем применить ту же логику к сравнению. Единственная разница в том, что мы работаем с известными датами - датами с дополнительной информацией о часовом поясе, в котором они находятся:

 from datetime import datetime 
 import pytz 
 
 # Create timezone objects for different parts of the world 
 tz_ny= pytz.timezone('America/New_York') 
 tz_lon = pytz.timezone("Europe/London") 
 
 # Year, Month, Day, Hour, Minute, Second 
 datetime = datetime(2010, 4, 20, 23, 30, 0) 
 
 # Localize the given date, according to the timezone objects 
 date_with_timezone_1 = tz_ny.localize(datetime) 
 date_with_timezone_2 = tz_lon.localize(datetime) 
 
 # These are now, effectively no longer the same *date* after being localized 
 print(date_with_timezone_1) # 2010-04-20 23:30:00-04:00 
 print(date_with_timezone_2) # 2010-04-20 23:30:00+01:00 
 
 print(date_with_timezone_1 == date_with_timezone_2) 

Выполнение этого кода приводит к:

 False 

Пока это заявление:

 print(date_with_timezone_1 > date_with_timezone_2) 

Это приведет к:

 True 

Этот результат может показаться вам немного странным . Мы сравниваем эти две даты:

 2010-04-20 23:30:00-04:00 # date_with_timezone_1 
 2010-04-20 23:30:00+01:00 # date_with_timezone_2 

Интуитивно кажется, что date_with_timezone_2 действительно больше date_with_timezone_1 . Но давайте посмотрим, как работает функция localize()

Здесь мы использовали pytz чтобы сделать наши наивные даты осведомленными. tz_ny объект часового пояса для Нью-Йорка (tz_ny) и объект часового пояса для Лондона ( tz_lon ).

Затем, чтобы ввести информацию о часовом поясе в наш datetime , мы запустили localize() и упаковали результат в date_with_timezone_1 и date_with_timezone_2 .

Мы поместили 23:30 в localize() , которая, в свою очередь, создала дату и время для 23:30 в Нью-Йорке и 23:30 в Лондоне соответственно. Чтобы добраться с 23:30 в Нью-Йорке до 23:30 в Лондоне, нужно добавить 4 часа. Прошло больше времени, чтобы добраться до Нью-Йорка до 23:30, чем до Лондона до 23:30. Таким образом, datetime, соответствующее Нью-Йорку в 23:30, больше, чем datetime, соответствующее Лондону в 23:30.

Помните об этом поведении при такой работе с часовыми поясами.

Однако стоит отметить, что сравнение известных дат с наивными датами приведет к ошибке:

 date_with_timezone = tz_ny.localize(datetime) 
 print(datetime == date_without_timezone) 

Это приведет к следующей ошибке:

 TypeError: can't compare offset-naive and offset-aware datetimes 

Итак, чтобы сравнивать объекты datetime, оба объекта должны быть либо наивными, либо осведомленными.

Заключение

В этой статье мы обсудили способы сравнения дат с привязкой к часовому поясу и без учета часовых поясов в Python, мы также рассмотрели возможные подводные камни, с которыми мы можем столкнуться при сравнении дат, и возможные обходные пути.

Если у вас есть какие-либо вопросы или предложения, пожалуйста, оставьте их в разделе комментариев ниже.

Licensed under CC BY-NC-SA 4.0
comments powered by Disqus