Найдите, прошло ли 24 часа между датами
У меня есть следующий метод:
# last_updated is a datetime() object, representing the last time this program ran
def time_diff(last_updated):
day_period = last_updated.replace(day=last_updated.day + 1,
hour=1,
minute=0,
second=0,
microsecond=0)
delta_time = day_period - last_updated
hours = delta_time.seconds // 3600
# make sure a period of 24hrs have passed before shuffling
if hours >= 24:
print "hello"
else:
print "do nothing"
Я хочу узнать, прошло ли с тех пор 24 часа last_updated
, как я могу это сделать на Python?
Переведено автоматически
Ответ 1
If last_updated
- наивный объект datetime, представляющий время в UTC:
from datetime import datetime, timedelta
if (datetime.utcnow() - last_updated) > timedelta(hours=24):
# more than 24 hours passed
If last_updated
- это местное время (наивный (не зависящий от часового пояса) объект datetime):
import time
DAY = 86400
now = time.time()
then = time.mktime(last_updated.timetuple())
if (now - then) > DAY:
# more than 24 hours passed
Если last_updated
время указано неоднозначно, например, время перехода в конце летнего периода (раз в год во многих часовых поясах), то вероятность того, что mktime()
вернет неверный результат (например, отклонение на час), равна пятидесяти на пятьдесят.
time.mktime()
также может произойти сбой, если time
библиотека C не использует базу данных исторических часовых поясов на данной платформе и смещение UTC для местного часового пояса отличалось в last_updated
время по сравнению с текущим. Это может применяться более чем к трети всех часовых поясов за последний год. В Linux, OS X, последних версиях Windows есть база данных tz (я не знаю, будут ли старые версии Windows работать для таких прошлых дат).
Осторожно: может возникнуть соблазн написать datetime.now() - last_updated
(аналогично случаю UTC), но это гарантированно завершится неудачей на всех платформах, если смещение UTC отличалось в last_updated
момент времени (это возможно во многих часовых поясах). Решение на основеmktime()
может использовать базу данных tz по крайней мере на некоторых платформах и, следовательно, может обрабатывать изменения смещения UTC по любой причине.
Для удобства переноса вы могли бы установить базу данных tz. Это обеспечивается pytz
модулем на Python. tzlocal
может возвращать pytz
часовой пояс, соответствующий местному часовому поясу:
from datetime import datetime, timedelta
from tzlocal import get_localzone # $ pip install tzlocal
tz = get_localzone() # local timezone
then = tz.normalize(tz.localize(last_updated)) # make it timezone-aware
now = datetime.now(tz) # timezone-aware current time in the local timezone
if (now - then) > timedelta(hours=24):
# more than 24 hours passed
Это работает, даже если в прошлом смещение UTC отличалось. Но это не может (а также time.mktime()
) исправить неоднозначное время (tz.localize()
выбирает is_dst=False
время по умолчанию). tz.normalize()
вызывается для корректировки несуществующих времен, например, тех, которые соответствуют переходу в начало летнего времени (это не должно влиять на результат).
Приведенный выше код предполагает, что last_updated
является наивным объектом datetime (без связанной информации о часовом поясе). Если last_updated
является осведомленным объектом datetime, то его легко преобразовать в UTC:
from datetime import datetime, timedelta
then_in_utc = last_updated.replace(tzinfo=None) - last_updated.utcoffset()
if (datetime.utcnow() - then_in_utc) > timedelta(hours=24):
# more than 24 hours passed
Общее примечание: теперь вы должны понять, почему люди рекомендуют работать со временем UTC и использовать местное время только для отображения.
Ответ 2
Просто чтобы прояснить некоторые моменты, потому что я не думаю, что все мы используем time
библиотеку Python. При использовании datetime
, что особенно в Django является очень распространенной практикой, если вы проводите сравнение следующим образом:
if (now - then) > DAY:
это приведет к огромному сбою. Это потому, что вы не можете сравнить datetime.timedelta
с int
.
Решение этой проблемы заключается в преобразовании ваших объектов в секунды.
Например:
from datetime import datetime
then = datetime_object
now = datetime.now()
if (now - then).total_seconds() > NUMBER_OF_SECONDS:
# do something
Надеюсь, я помог всем, кто сталкивался с проблемами по этому поводу.
Приветствия