如何在时区找到下一个上午7点

时间:2016-04-13 01:26:22

标签: python python-2.7 date datetime

current_datetime = datetime.now(tz)
next_hour = datetime(current_datetime.year, current_datetime.month, current_datetime.day, 7, 0, 0, 0, tz)
timedelta_until_next_hour = next_hour - current_datetime
if timedelta_until_next_hour.total_seconds() < 0:
    timedelta_until_next_hour += timedelta(days=1)
return timedelta_until_next_hour.total_seconds()

我试图在下一次上午7点找到当地时区,并返回到此为止的秒数。

我有一些夏令时问题。例如:America/New_York current_datetime的utcoffset为-4小时 虽然next_hour的偏移量为-5小时,但两者相减一小时

2 个答案:

答案 0 :(得分:1)

找到下一个上午7点

您可以使用python-dateutil的{​​{3}}:

轻松完成此操作
from dateutil.relativedelta import relativedelta
def next_7am(dt):
    relative_days = (dt.hour >= 7)
    absolute_kwargs = dict(hour=7, minute=0, second=0, microsecond=0)
    return dt + relativedelta(days=relative_days, **absolute_kwargs)

它的工作方式是relativedelta采用绝对参数(用单数表示,例如monthyearday )和相对参数(用复数形式表示,例如monthsyearsdays)。如果您向relativedelta添加datetime对象,它将替换datetime中的绝对值,然后添加relative值,那么我上面已经指出relative_days应该是1如果它已经是早上7点,否则它应该是0,绝对参数说“用7 AM替换时间”。将其添加到您的日期时间,它将在下一个上午7点为您提供。

处理时区

下一步取决于您所使用的时区。如果您使用的是dateutil时区,则可以使用上面定义的函数:

dt_next_7am = next_7am(dt)

如果您使用pytz时区,则应将其剥离并将计算作为天真的日期时间,然后重新定位时区,如下所示:

dt_next_7am = tz.localize(next_7am(dt.replace(tzinfo=None)))

如果你想获得这两次之间的绝对小时数,你应该用UTC做算术:

time_between = dt_next_7am.astimezone(tz=UTC) - dt.astimezone(tz=UTC)

UTC被定义为dateutil.tz.tzutc()pytz.UTC或等效的地方。

DST转换的示例

以下是使用dateutil的示例(评论中包含结果):

from datetime import datetime
from dateutil.tz import gettz, tzutc

LA = gettz('America/Los_Angeles')
dt = datetime(2011, 11, 5, 12, 30, tzinfo=LA)
dt7 = next_7am(dt)

print(dt7.astimezone(tzutc()) - dt.astimezone(tzutc()))  # 19:30:00

一个示例显示使用pytz执行此操作的错误和正确方法:

from datetime import datetime
import pytz
LA = pytz.timezone('America/Los_Angeles')
UTC = pytz.UTC

dt = LA.localize(datetime(2011, 11, 5, 12, 30))
dt7_bad = next_7am(dt)      # pytz won't like this
dt7_good = LA.localize(next_7am(dt.replace(tzinfo=None)))

dt_utc = dt.astimezone(pytz.UTC)
print(dt7_bad.astimezone(pytz.UTC) - dt_utc)   # 18:30:00 (Wrong)
print(dt7_good.astimezone(pytz.UTC) - dt_utc)  # 19:30:00 (Right)

不明确/不存在上午7点

如果您正在处理某些区域中的某些日期,特别是那些会导致模糊时间的日期在以下列表中(截至2016年4月):

1901-12-13 07:00:00 (/Pacific/Fakaofo)
1901-12-14 07:00:00 (/Asia/Kamchatka)
1901-12-14 07:00:00 (/Asia/Ust-Nera)
1901-12-14 07:00:00 (/Pacific/Bougainville)
1901-12-14 07:00:00 (/Pacific/Kosrae)
1901-12-14 07:00:00 (/Pacific/Majuro)
1917-03-25 07:00:00 (/Antarctica/Macquarie)
1918-03-31 07:00:00 (/EST5EDT)
1919-03-31 07:00:00 (/Antarctica/Macquarie)
1952-01-13 07:00:00 (/Antarctica/DumontDUrville)
1954-02-13 07:00:00 (/Antarctica/Mawson)
1957-01-13 07:00:00 (/Antarctica/Davis)
1969-01-01 07:00:00 (/Antarctica/Casey)
1969-02-01 07:00:00 (/Antarctica/Davis)
1969-09-29 07:00:00 (/Kwajalein)
1969-09-29 07:00:00 (/Pacific/Kwajalein)
1979-09-30 07:00:00 (/Pacific/Enderbury)
1979-09-30 07:00:00 (/Pacific/Kiritimati)
2009-10-18 07:00:00 (/Antarctica/Casey)
2011-09-23 07:00:00 (/Pacific/Apia)
2011-10-28 07:00:00 (/Antarctica/Casey)

然后得到的7AM值将是不明确的或不存在的。如果要处理这些边缘情况,请参阅relativedelta module。值得注意的是,在this answer实施后,处理模糊时间可能会略有不同。

使用python-dateutil的{​​{1}}模块生成重复规则和rrule区域方法的替代实现如下(请注意,这将适用于非pytz区域,但它不能正确解决模糊/不存在的时间):

pytz

答案 1 :(得分:-2)

  

我正试图在下一次上午7点找到当地时区,然后返回秒数。

使用the same code as for dt6 (replace time(6) with time(7))查找dt7

然后直到(dt7 - now).total_seconds()的秒数。

请参阅the bullet points that explain when other solutions may fail