Rukovodstvo
статьи и идеи для разработчиков программного обеспечения и веб-разработчиков.
Сравнение дат и времени в Python — с часовыми поясами и без них
Введение При работе с датами часто бывает необходимо знать, наступает ли данная дата до или после другой даты. Мы можем получить эти ответы, сравнив даты. В этой статье мы узнаем, как использовать модуль Python datetime для создания и сравнения как простых (без информации о часовом поясе), так и известных (с информацией о часовом поясе) дат. Для сравнения дат мы будем использовать операторы сравнения в Python: <,>, ==, <=,> =,! =. Примечание. В модуле datetime есть два метода создания объекта даты — d
Время чтения: 4 мин.
Вступление
Часто при работе с датами вам нужно знать, наступает ли данная дата до или после другой даты. Мы можем получить эти ответы, сравнив даты.
В этой статье мы узнаем, как использовать 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)
Сравнить эти объекты так же просто, как сравнить, скажем, целые числа. Дата меньше другой, если ее время предшествует другому.
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
Как сравнивать даты в python
Для форматирования объектов date и time в обоих этих классах предусмотрен метод strftime(format) . Этот метод принимает только один параметр, указывающий на формат, в который нужно преобразовать дату или время.
Для определения формата мы можем использовать один из следующих кодов форматирования:
- %a : аббревиатура дня недели. Например, Wed — от слова Wednesday (по умолчанию используются английские наименования)
- %A : день недели полностью, например, Wednesday
- %b : аббревиатура названия месяца. Например, Oct (сокращение от October)
- %B : название месяца полностью, например, October
- %d : день месяца, дополненный нулем, например, 01
- %m : номер месяца, дополненный нулем, например, 05
- %y : год в виде 2-х чисел
- %Y : год в виде 4-х чисел
- %H : час в 24-х часовом формате, например, 13
- %I : час в 12-ти часовом формате, например, 01
- %M : минута
- %S : секунда
- %f : микросекунда
- %p : указатель AM/PM
- %c : дата и время, отформатированные под текущую локаль
- %x : дата, отформатированная под текущую локаль
- %X : время, форматированное под текущую локаль
Используем различные форматы:
from datetime import datetime now = datetime.now() print(now.strftime("%Y-%m-%d")) # 2017-05-03 print(now.strftime("%d/%m/%Y")) # 03/05/2017 print(now.strftime("%d/%m/%y")) # 03/05/17 print(now.strftime("%d %B %Y (%A)")) # 03 May 2017 (Wednesday) print(now.strftime("%d/%m/%y %I:%M")) # 03/05/17 01:36
При выводе названий месяцев и дней недели по умолчанию используются английские наименования. Если мы хотим использовать текущую локаль, то мы можем ее предварительно установить с помощью модуля locale:
from datetime import datetime import locale locale.setlocale(locale.LC_ALL, "") now = datetime.now() print(now.strftime("%d %B %Y (%A)")) # 03 Май 2017 (среда)
Сложение и вычитание дат и времени
Нередко при работе с датами возникает необходимость добавить к какой-либо дате определенный промежуток времени или, наоборот, вычесть некоторый период. И специально для таких операций в модуле datetime определен класс timedelta . Фактически этот класс определяет некоторый период времени.
Для определения промежутка времени можно использовать конструктор timedelta:
timedelta([days] [, seconds] [, microseconds] [, milliseconds] [, minutes] [, hours] [, weeks])
В конструктор мы последовательно передаем дни, секунды, микросекунды, миллисекунды, минуты, часы и недели.
Определим несколько периодов:
from datetime import timedelta three_hours = timedelta(hours=3) print(three_hours) # 3:00:00 three_hours_thirty_minutes = timedelta(hours=3, minutes=30) # 3:30:00 two_days = timedelta(2) # 2 days, 0:00:00 two_days_three_hours_thirty_minutes = timedelta(days=2, hours=3, minutes=30) # 2 days, 3:30:00
Используя timedelta, мы можем складывать или вычитать даты. Например, получим дату, которая будет через два дня:
from datetime import timedelta, datetime now = datetime.now() print(now) # 2017-05-03 17:46:44.558754 two_days = timedelta(2) in_two_days = now + two_days print(in_two_days) # 2017-05-05 17:46:44.558754
Или узнаем, сколько было времени 10 часов 15 минут назад, то есть фактически нам надо вычесть из текущего времени 10 часов и 15 минут:
from datetime import timedelta, datetime now = datetime.now() till_ten_hours_fifteen_minutes = now - timedelta(hours=10, minutes=15) print(till_ten_hours_fifteen_minutes)
Свойства timedelta
Класс timedelta имеет несколько свойств, с помощью которых мы можем получить временной промежуток:
- days : возвращает количество дней
- seconds : возвращает количество секунд
- microseconds : возвращает количество микросекунд
Кроме того, метод total_seconds() возвращает общее количество секунд, куда входят и дни, и собственно секунды, и микросекунды.
Например, узнаем какой временной период между двумя датами:
from datetime import timedelta, datetime now = datetime.now() twenty_two_may = datetime(2017, 5, 22) period = twenty_two_may - now print("<> дней <> секунд <> микросекунд".format(period.days, period.seconds, period.microseconds)) # 18 дней 17537 секунд 72765 микросекунд print("Всего: <> секунд".format(period.total_seconds())) # Всего: 1572737.072765 секунд
Сравнение дат
Также как и строки и числа, даты можно сравнивать с помощью стандартных операторов сравнения:
from datetime import datetime now = datetime.now() deadline = datetime(2017, 5, 22) if now > deadline: print("Срок сдачи проекта прошел") elif now.day == deadline.day and now.month == deadline.month and now.year == deadline.year: print("Срок сдачи проекта сегодня") else: period = deadline - now print("Осталось <> дней".format(period.days))
Как сравнить 2 даты?
В интернете наше что сравнивать можно даты в формате библиотеки datetime . у меня есть date = time.struct_time(tm_year=2019, tm_mon=11, tm_mday=1, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=4, tm_yday=305, tm_isdst=-1) и я пытаюсь сравнить с текущей датой :
if date < datetime.datetime.today(): print('1') else: print('0')
однако ни ошибки , ни результата нету , то есть это условие как будто игнорируется.
- Вопрос задан более двух лет назад
- 297 просмотров
2 комментария
Простой 2 комментария
Сравнение дат в datetime
Вы переводите формат datetime.datetime и datetime.date в строки (именно это делает метод strftime ), и потом их сравниваете. Разумеется, строка 09.11.2020 больше строки 05.07.3000 .
Сравнивать нужно непосредственно данные в форматах datetime:
dt.datetime.now() < dt.datetime(3000, 7, 5) # True
UPDATE
Если вам изначально дана строка, то переведите ее в формат dateimte и сравнивайте:
import datetime as dt my_string = "07.02.3000" my_dt = dt.datetime.strptime(my_string, '%d.%m.%Y') print(my_dt > dt.datetime.now()) # True