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小时,但两者相减一小时
答案 0 :(得分:1)
您可以使用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
采用绝对参数(用单数表示,例如month
,year
,day
)和相对参数(用复数形式表示,例如months
,years
,days
)。如果您向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
或等效的地方。
以下是使用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)
如果您正在处理某些区域中的某些日期,特别是那些会导致模糊时间的日期在以下列表中(截至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。