【问题标题】:Find if 24 hrs have passed between datetimes查找日期时间之间是否经过了 24 小时
【发布时间】:2023-03-12 10:14:01
【问题描述】:

我有以下方法:

# 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"

我想知道自 last_updated 以来是否已经过了 24 小时,我该如何在 Python 中做到这一点?

【问题讨论】:

  • 最后更新的格式是什么?
  • 什么是last_updated?是当地时间吗?你想知道是超过 24 小时还是第二天的当前时间更大,例如 last_updated=Nov 1, 7pm 并且当前时间是 Nov 2, 6:30pm(超过 24 小时,但是下午 6:30 是不到晚上 7 点)(在纽约)。
  • @PadraicCunningham 我已经更新了问题...... last_updated 是一个 datetime() ,它告诉程序上次更新的时间。如果自上次更新以来已经过去了 24 小时,我现在需要做的就是(从现在())
  • @J.F.Sebastian 查看对 PadraicCunningham 的评论

标签: python datetime timezone


【解决方案1】:

如果 last_updated 是一个简单的日期时间对象,表示 UTC 时间:

from datetime import datetime, timedelta

if (datetime.utcnow() - last_updated) > timedelta(hours=24): 
    # more than 24 hours passed

如果last_updated 是本地时间(naive (timezone-unaware) 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 是一个不明确的时间,例如,DST 过渡结束期间的时间(在许多时区中每年一次),那么mktime() 返回错误结果的可能性有 550 倍(例如,关闭一个小时)。

如果 C time 库在给定平台上不使用历史时区数据库,time.mktime() 也可能失败并且本地时区的 UTC 偏移量在 last_updated 比较时不同到现在。它可能适用于去年超过三分之一的时区。 Linux、OS X、Windows 的最新版本都有 tz 数据库(我不知道旧的 Windows 版本是否适用于这些过去的日期)。

注意:写datetime.now() - last_updated 可能很诱人(类似于UTC 的情况),但如果last_updated 时间的UTC 偏移量不同(在许多时区都有可能),则保证在所有平台上都会失败。基于mktime() 的解决方案至少可以在某些平台上使用 tz 数据库,因此它可以处理那里无论出于何种原因的 UTC 偏移量的变化。

为了便携性,您可以安装 tz 数据库。它由 Python 中的pytz 模块提供。 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() 来调整不存在的时间,例如,对应于 DST 转换开始的时间(它不应该影响结果)。

上面的代码假定last_updated 是一个简单的日期时间对象(没有关联的时区信息)。如果last_updated 是一个可感知的日期时间对象,那么很容易将其转换为 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.timedeltaint 进行比较。

    解决方案是将您的对象转换为秒。
    例如:

    from datetime import datetime
    
    then = datetime_object
    now = datetime.now()
    
    if (now - then).total_seconds() > NUMBER_OF_SECONDS:
        # do something
    

    希望我能帮助遇到这方面问题的人。
    干杯

    【讨论】:

    • 1.注意:timedelta(1) 在我的回答 2 中。注意:我的回答是关于 datetime.now() 的内容以及为什么不应该使用它。 3. django 对应于我的答案中的最后一个代码示例,带有时区感知日期时间对象(更简单的情况)——确保USE_TZ=True 并使用timezone.now() 而不是datetime.now()
    • 当然,您的回答是 100% 正确且有价值的,我只是想在需要时指出 total_seconds() 的用法。我完全同意timezone.now() btw。
    猜你喜欢
    • 2021-08-06
    • 2020-08-15
    • 1970-01-01
    • 2023-01-15
    • 2020-01-05
    • 1970-01-01
    • 1970-01-01
    • 2010-10-01
    • 1970-01-01
    相关资源
    最近更新 更多