在Python中,我可以找到本地时间的Unix时间戳,知道时区,如下所示(使用pytz):
>>> import datetime as DT
>>> import pytz
>>> mtl = pytz.timezone('America/Montreal')
>>> naive_time3 = DT.datetime.strptime('2013/11/03', '%Y/%m/%d')
>>> naive_time3
datetime.datetime(2013, 11, 3, 0, 0)
>>> localized_time3 = mtl.localize(naive_time3)
>>> localized_time3
datetime.datetime(2013, 11, 3, 0, 0, tzinfo=<DstTzInfo 'America/Montreal' EDT-1 day, 20:00:00 DST>)
>>> localized_time3.timestamp()
1383451200.0
到目前为止,还不错。naive_time
不知道时区,而{
现在,在蒙特勒亚尔,11月3日下午2点,时钟调整了一个小时,所以那天我们又多了一个小时。这意味着,在2013年11月3日至2013年11月4日期间,25小时。这表明:
>>> naive_time4 = DT.datetime.strptime('2013/11/04', '%Y/%m/%d')
>>> localized_time4 = mtl.localize(naive_time4)
>>> localized_time4
datetime.datetime(2013, 11, 4, 0, 0, tzinfo=<DstTzInfo 'America/Montreal' EST-1 day, 19:00:00 STD>)
>>> (localized_time4.timestamp() - localized_time3.timestamp()) / 3600
25.0
现在,我正在寻找一种从localized_time3
获取localized_time4
对象的简单方法,因为我知道我希望在下一个本地化的日期在同一时间(这里是午夜)。我试过timedelta
,但我相信它不知道时区或夏令时:
>>> localized_time4td = localized_time3 + DT.timedelta(1)
>>> localized_time4td
datetime.datetime(2013, 11, 4, 0, 0, tzinfo=<DstTzInfo 'America/Montreal' EDT-1 day, 20:00:00 DST>)
>>> (localized_time4td.timestamp() - localized_time3.timestamp()) / 3600
24.0
我的目的是获取与日志条目相关的信息,这些日志条目存储在Unix时间戳中,用于每个本地日。当然,如果我使用localized_time3.timestamp()
并在这里添加24 * 3600
(这将与localized_time4td.timestamp()
相同),我将错过localized_time4td.timestamp()
和{
换句话说,我要查找的函数或方法应该知道何时将25小时、24小时或23小时添加到Unix时间戳中,这取决于DST转换发生的时间。在
不使用新软件包:
完整脚本:
^{pr2}$(
calendar
代表Python。)我逐渐地在这个答案的末尾提供了几种解决方案,这些方案试图解决以下问题:
dateutil
和stdlib解决方案在某些系统(尤其是Windows)上失败Arrow
是否提供了处理它的接口)要查找给定时区中明天午夜(或其他固定时间)的POSIX时间戳,可以使用How do I get the UTC time of “midnight” for a given timezone?中的代码:
dt.date()
方法为朴素对象和时区感知对象返回相同的初始日期dt
。在时间戳的显式公式用于支持python3.3之前的Python版本。否则,
.timestamp()
方法可以在python3.3+中使用。在为了避免在DST转换期间解析输入日期时出现歧义,而这种歧义对于
^{pr2}$.localize()
方法是不可避免的,除非您知道is_dst
参数,您可以使用与日期一起存储的Unix时间戳:要支持其他固定时间(不仅是午夜):
如果结果日期不明确或不存在,
is_dst=None
将引发异常。为了避免出现异常,您可以选择最接近昨天的前一个日期的时间(相同的DST状态,即is_dst=local_dt.dst()
):.localize()
尊重给定的时间,即使它不存在,因此需要.normalize()
来确定时间。如果normalize()
方法更改其输入(在本例中检测到不存在的时间)以与其他代码示例保持一致,则可以在此处引发异常。在(感谢@rdodev将我指向Arrow)。在
使用箭头,此操作变得简单:
使用Arrow的
replace
方法,单数单元名替换该属性,而复数则添加到该属性中。所以lt3.replace(days=1)
是2013年11月4日,lt3.replace(day=1)
是2013年11月1日。在相关问题 更多 >
编程相关推荐