两个timedelta对象的差异,带时区

2024-10-03 09:08:42 发布

您现在位置:Python中文网/ 问答频道 /正文

我想计算一个日期间隔中有多少小时:例如“2014.03.29-30”应该是47,因为夏令时。在

我的方法是生成两个datetime对象,在下面的示例中:

datetime.datetime(2014, 3, 29, 0, 0, tzinfo=<DstTzInfo 'Europe/Budapest' LMT+1:16:00 STD>)
datetime.datetime(2014, 3, 30, 23, 59, tzinfo=<DstTzInfo 'Europe/Budapest' LMT+1:16:00 STD>)
return (date2-date1) + timedelta(minutes=1)

但是,它给出了“2天,0:00:00”,这是不正确的。如何制作一个考虑时区和dst的timedelta对象?另外,如果有更简单的方法来解决整个问题,我愿意接受。在

谢谢你!在


Tags: 对象方法示例datetime间隔returntimedeltastd
1条回答
网友
1楼 · 发布于 2024-10-03 09:08:42

在1901-12-13 20:45:52 UTC之前,'Europe/Budapest'时区是LMT+1:16:00 STD。 目前,截至2016-05-05,'Europe/Budapest'时区为CET+2:00:00DST。在

如果使用pytz的^{} method,那么pytz将为'Europe/Budapest'选择适合给定原始日期时间的时区(utcoffset和dstoffset):

import datetime as DT
import pytz

tzone = pytz.timezone('Europe/Budapest')
date1 = tzone.localize(DT.datetime(2014, 3, 29, 0, 0), is_dst=None)
# datetime.datetime(2014, 3, 29, 0, 0, tzinfo=<DstTzInfo 'Europe/Budapest' CET+1:00:00 STD>)

相反,如果您将tzinfo=tzone直接提供给datetime.datetime,如:

^{2}$

然后datetime.datetime错误地选择了与'Europe/Budapest'相关联的第一个时区,而不管这是否是2014年3月29日生效的时区。在

因此,在使用pytz时,请始终使用tzone.localize使naivedatetimes时区感知:

import datetime as DT
import pytz
tzone = pytz.timezone('Europe/Budapest')
date1 = tzone.localize(DT.datetime(2014, 3, 29, 0, 0), is_dst=None)
date2 = tzone.localize(DT.datetime(2014, 3, 30, 23, 59), is_dst=None)
print(((date2-date1) + DT.timedelta(minutes=1)).total_seconds()/3600.)
# 47.0

Do not use ^{}除非tzonepytz.utc(或者在其历史上一直是相同的时区)


日期是从哪里来的?

您可以使用pytz时区的tzone._utc_transition_timestzone._transition_info私有属性来查看pytz时区的utc转换时间(以及相关的转换信息):

In [43]: [(utcdate, utcoffset, dstoffset, tzabbrev) for utcdate, (utcoffset, dstoffset, tzabbrev) in zip(tzone._utc_transition_times, tzone._transition_info)][:2]
Out[43]: 
[(datetime.datetime(1, 1, 1, 0, 0),
  datetime.timedelta(0, 4560),
  datetime.timedelta(0),
  'LMT'),
 (datetime.datetime(1901, 12, 13, 20, 45, 52),
  datetime.timedelta(0, 3600),
  datetime.timedelta(0),
  'CET')]

这表明从1-1-1 UTC1901-12-13 20:45:52 UTC,时区缩写是LMT,utcoffset是4560秒,等于1小时16分钟:

In [47]: print(DT.timedelta(0, 4560))
1:16:00

因此,与'Europe/Budapest'相关联的第一个时区是LMT+1:16:00 STD。在

相关问题 更多 >