Как сравнивать время в python
Перейти к содержимому

Как сравнивать время в python

  • автор:

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

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

В этой статье мы узнаем, как использовать Python модуль 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_lon ).

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

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

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

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

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

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

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

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

Как сравнить время в python?

Привет qna!У меня есть бот с виртуальной экономикой. Там есть команда !work. Я записываю время в файл. Потом мне нужно сравнить время. К на разницу в 10 минут и больше.

  • Вопрос задан более двух лет назад
  • 1314 просмотров

Комментировать
Решения вопроса 1

MinTnt

Зависит от того, в каком формате записываете?
Если под записанным временнем имеется ввиду time.time()

То условие для проверки можно сделать так:

#Допустим K это время что сохраненно в файле if (time.time()-K) > 60 * 10:

Классы time и timezone модуля datetime. Работа со временем в Python

Экземпляры, создаваемые от класса time модуля datetime , предназначены для хранения времени суток (без даты).

Вызов конструктора time без передачи аргументов создает объект времени полуночи (начала суток), а не текущего момента.

Вызов конструктора объекта time без аргументов

В конструктор можно передать час, минуту, секунду и микросекунду (одна миллионная секунды) фиксируемого момента. Все аргументы являются опциональными.

from datetime import time a = time(10, 30) print(a.strftime("%H:%M")) # 10:30 b = time(minute=3, second=37) print(b) # 00:03:37 c = time(microsecond=830_000) print(c.microsecond) # 830000 print(c.__repr__()) # datetime.time(0, 0, 0, 830000)

Класс time модуля datetime не выполняет автоматическое преобразование значений, превышающих 59 минут в часы и секунд в минуты, больше 23 часа – в сутки, а значение в один миллион микросекунд – в секунду. Поэтому числовые параметры hour , minute , second , microsecond имеют соответствующие им ограничения.

Количество часов должно быть меньше 24

По аналогии с date , объект time можно получить из строки соответствующего ISO-формата, используя классовый метод fromisoformat .

from datetime import time a = time.fromisoformat("20:18:30") print("A:", a) print(repr(a)) b = time.fromisoformat("00:02:09:004000") print("\nB:", b) print(repr(b)) c = time.fromisoformat("11:00+03:00") print("\nC:", c) print(repr(c))
A: 20:18:30 datetime.time(20, 18, 30) B: 00:02:09.004000 datetime.time(0, 2, 9, 4000) C: 11:00:00+03:00 datetime.time(11, 0, tzinfo=datetime.timezone(datetime.timedelta(seconds=10800)))

В примере при создании третьего объекта мы указываем смещение времени от UTC (всемирного времени – это примерно то же самое, что по Гринвичу – GMT). При этом у объекта свойство tzinfo оказывается связанным с экземпляром timezone .

Хотя в литерале «11:00+03:00» пишется плюс, если в часовом поясе, отстоящем от UTC на три часа на восток, 11 часов утра, то в этот самый момент в часовом поясе, где непосредственно действует UTC, будет 8 часов утра, то есть на три часа меньше. Если переместиться от UTC на один часовой пояс на запад, там будет 7 часов утра: «07:00-01:00» .

from datetime import time utc = time.fromisoformat("08:00+00:00") east3 = time.fromisoformat("11:00+03:00") west1 = time.fromisoformat("07:00-01:00") print(east3 == utc) # True print(east3 == west1) # True

Из примера мы видим, что в Python объекты времени можно сравнивать между собой. Однако лучше этого не делать, если одним операндом является «осведомленное» (aware) время, а другим – «наивное» (naive), то есть время без часового пояса. В таких случаях оператор == всегда возвращает False , != всегда True , а сравнения > , , >= , недопустимы (выбрасывается TypeError ). Поэтому следует сравнивать либо только экземпляры времени с часовым поясом, либо только без него.

Сравнение объектов времени

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

Вернемся к получению объекта через конструктор и рассмотрим параметр tzinfo , которому присваивается экземпляр timezone , который создается через передачу в его конструктор экземпляра timedelta .

from datetime import time, timezone, timedelta tz = timezone(timedelta(hours=10, minutes=50)) a = time(12, 35, 28, tzinfo=tz) b = time(11, 40, tzinfo=timezone(timedelta(hours=-5))) print(a) # 12:35:28+10:50 print(b) # 11:40:00-05:00

В данном случае на таймдельту накладываются ограничения. Задаваемый промежуток времени должен быть по модулю меньше длины одних суток.

С помощью метода utcoffset можно получить смещение времени относительно UTC. Если быть точнее, метод просто возвращает ссылку на объект таймдельты.

from datetime import time, timezone, timedelta a = time(12, tzinfo=timezone(timedelta(hours=3))) b = time(11, tzinfo=timezone(timedelta(hours=-1))) a_offset = a.utcoffset() b_offset = b.utcoffset() print(a_offset) print(a_offset.__repr__(), end="\n\n") print(b_offset) print(b_offset.__repr__()) print("\nРазница в часовых поясах:") print(abs(b_offset - a_offset))
3:00:00 datetime.timedelta(seconds=10800) -1 day, 23:00:00 datetime.timedelta(days=-1, seconds=82800) Разница в часовых поясах: 4:00:00

Такое странное представление смещения от UTC на 1 час меньше (минус 1 день плюс 23 часа) связано с внутренним устройством объектов timedelta . У них нет свойства hours , поэтому часы конвертируются в секунды. Кроме того свойство seconds не может хранить отрицательных значений.

Узнать смещение можно не только через метод utcoffset экземпляра time . Также можно обратиться к полю tzinfo этого же экземпляра. Однако следует иметь в виду, что последнее связано с экземпляром timezone , который имеет свой метод utcoffset . И в данном случае в него надо передавать None .

from datetime import time, timezone, timedelta a = time(12, tzinfo=timezone(timedelta(hours=3))) print(a.tzinfo) # UTC+03:00 offset = a.tzinfo.utcoffset(None) # экземпляр timedelta print(offset) # 3:00:00 zn = a.tzinfo.tzname(None) # экзепляр str print(zn) # UTC+03:00

Метод tzname есть и у time . Он также возвращает строку в формате UTC±HH:MM, если только не было задано произвольное наименование часового пояса.

from datetime import time, timezone, timedelta a = time(12, tzinfo=timezone(timedelta(hours=3), name="Moscow")) b = time(8, tzinfo=timezone(timedelta(hours=0))) print(a.tzname()) # Moscow print(b.tzname()) # UTC

В мире существуют не только разные часовые пояса. Также в ряде стран переходят на так называемое летнее время (daylight saving time – DST), когда в течение полугода к стандартному смещению часового пояса от UTC добавляется еще один час. Обычно это делают в последнее воскресенье марта, а возвращаются к стандартному поясному времени в последнее воскресенье октября.

Класс timezone не позволяет учитывать DST. Однако на самом деле не обязательно передавать параметру tzinfo объект типа timezone . Самое главное передавать туда экземпляр, созданный от любого подкласса класса tzinfo . Класс timezone является одним из подклассов этого класса.

Другими словами, вы можете написать свой класс, который будет работать с DST.

Обратим внимание, что есть параметр tzinfo конструктора time , есть соответствующее ему свойство объекта, а есть абстрактный класс tzinfo модуля datetime .

При создании экземпляров от datetime не обязательно разрабатывать свой подкласс от tzinfo , чтобы учитывать не только часовые пояса, но и переход на летнее время. В Python есть готовое решение в виде модуля zoneinfo , который подключается к внешней базе данных часовых поясов (есть в системе или устанавливается отдельно). Класс ZoneInfo из модуля zoneinfo является наследником класса tzinfo из модуля datetime .

Атрибуты класса time (подчеркнуты не упомянутые в уроке):

  • данные, хранимые в классе (свойства класса): min , max , resolution
  • методы класса: fromisoformat
  • свойства экземпляра: hour , minute , second , microsecond , tzinfo , fold
  • методы экземпляра: replace , isoformat , strftime , utcoffset , dst , tzname

X Скрыть Наверх

Даты и время в Python. Курс

Как сравнивать время в python

Шаг 107.
Основы языка Python. Работа с датой и временем. Модуль datetime. Манипуляции датой и временем. Класс datetime (окончание)

На этом шаге мы рассмотрим основные методы этого класса .

  • datetime2 = datetime1 + timedelta — прибавляет к дате указанный период;
  • datetime2 = datetime1 — timedelta — вычитает из даты указанный период;
  • timedelta = datetime1 — datetime2 — возвращает разницу между датами;
  • можно также сравнивать две даты с помощью операторов сравнения.

>> d1 = datetime.datetime (2017, 11, 10, 16, 7, 22) >> d2 = datetime.datetime (2017, 11, 20, 16, 7, 22) >> t = datetime.timedelta (days=10, minutes=10) >> d1 + t # Прибавляем 10 дней и 10 минут datetime.datetime(2017, 11, 20, 16, 17, 22) >> d1 - t # Вычитаем 10 дней и 10 минут datetime.datetime(2017, 10, 31, 15, 57, 22) >> d1 - d2 # Разница между датами datetime.timedelta(-10)(5, 12978) >> d1 < d2, d1 >d2, d1 = d2 (True, False, True, False) >> d1 == d2, d1 != d2 (False, True) 


    date () — возвращает экземпляр класса date , хранящий дату:

>> d = datetime.datetime (2017, 11, 10, 16, 10, 54) >> d.date() datetime.date(2017, 11, 10) 
>> d = datetime.datetime (2017, 11, 10, 16, 10, 54) >> d.time() datetime.time(16, 10, 54) 
>> d = datetime.datetime (2017, 11, 10, 16, 10, 54) >> d.timestamp() 1510312254.0 
>> d = datetime.datetime (2017, 11, 10, 16, 10, 54) >> d.replace (2014, 12) datetime.datetime(2014, 12, 10, 16, 10, 54) >> d.replace (hour=12, month=10) datetime.datetime(2017, 10, 10, 12, 10, 54) 
>> d = datetime.datetime (2017, 11, 10, 16, 10, 54) >> d.timetuple() time.struct_time(tm_year=2017, tm_mon=11, tm_mday=10, tm_hour=16, tm_min=10, tm_sec=54, tm_wday=4, tm_yday=314, tm_isdst=-1) 
>> d = datetime.datetime (2017, 11, 10, 16, 10, 54) >> d.utctimetuple () time.struct_time(tm_year=2017, tm_mon=11, tm_mday=10, tm_hour=16, tm_min=10, tm_sec=54, tm_wday=4, tm_yday=314, tm_isdst=0) 
>> d.toordinal() 736643 
>> d = datetime.datetime (2017, 11, 10, 16, 10, 54) >> d.weekday() # 4 - это пятница 4 
>> d = datetime.datetime (2017, 11, 10, 16, 10, 54) >> d.isoweekday() # 5 - это пятница 5 
>> d = datetime.datetime (2017, 11, 10, 16, 10, 54) >> d.isocalendar() (2017, 45, 5) 
>> d = datetime.datetime (2017, 11, 10, 16, 10, 54) >> d.isoformat () # Разделитель не указан '2017-11-10T16:10:54' >> d.isoformat (" ") # Пробел в качестве разделителя '2017-11-10 16:10:54' 
>> d = datetime.datetime (2017, 11, 10, 16, 10, 54) >> d.ctime() 'Fri Nov 10 16:10:54 2017' 
>> d.strftime ("%d.%m.%Y %H:%M:%S") '10.11.2017 16:10:54' 

  • min — минимально возможные значения даты и времени;
  • max — максимально возможные значения даты и времени;
  • resolution — минимальное возможное различие между значениями даты и времени.

Значения этих атрибутов:

>> datetime.datetime.min datetime.datetime(1, 1, 1, 0, 0) >> datetime.datetime.max datetime.datetime(9999, 12, 31, 23, 59, 59, 999999) >> datetime.datetime.resolution datetime.timedelta(0, 0, 1) 

Примечание . Экземпляры класса datetime поддерживают также методы astimezone () , dst () , utcoffset () и tzname () . За подробной информацией по этим методам, а также по абстрактному классу tzinfo , обращайтесь к документации по модулю datetime .

На следующем шаге мы рассмотрим модуль calendar .

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *