在 DST 更改发生时将字符串解析为日期
Posted
技术标签:
【中文标题】在 DST 更改发生时将字符串解析为日期【英文标题】:Parsing a string into date at the time the DST change happened 【发布时间】:2020-02-23 03:39:36 【问题描述】:在西欧,2019-10-27 02:30:00
可能是“两个”时间事件:
datetime
parser 和 pytz
如何处理解析此日期可能导致两个不同时间事件的事实?
import datetime, pytz
d = datetime.datetime.strptime("2019-10-27 02:30:00", '%Y-%m-%d %H:%M:%S')
d = pytz.timezone('Europe/Paris').localize(d)
print(d, d.timestamp())
答案是2019-10-27 02:30:00+01:00 1572139800.0
,为什么不是2019-10-27 02:30:00+02:00
?这两个都有可能。
备注:
import datetime
print(datetime.datetime.fromtimestamp(1572139800.0)) # 2019-10-27 02:30:00
print(datetime.datetime.fromtimestamp(1572136200.0)) # 2019-10-27 02:30:00
(这两个不同的 UTC 时间戳在欧洲/巴黎时区确实具有相同的日期时间)
【问题讨论】:
【参考方案1】:方向由localize
方法的is_dst
参数确定。
is_dst 用于在歧义中确定正确的时区 夏令时结束时的时段。
在问题的示例中,使用True
会给你+02:00;和False
+01:00
使用 is_dst=None 来引发 AmbiguousTimeError 夏令时结束时的时间
如果 datetime 实例是幼稚的(或不包含时区),使用 localize
将应用时区,假设提供的实例是本地时间,并将偏移量应用于目标时区。
使用localize
后,日期时间实例将不再是幼稚的,两个值将彼此相等,因为它们在技术上是相同的时间。
这个问题突出了 datetime
模块的一个恼人行为,除非明确指定 datetime
实例是幼稚的,这包括在匹配表达式不包含时间偏移的情况下使用 strptime
。
通过更改示例以包含可选的时区参数,事情变得更加清晰:
import pytz
from datetime import datetime
tz = pytz.timezone("Europe/Paris")
print(datetime.fromtimestamp(1572139800.0, tz)) # 2019-10-27 02:30:00+01:00
print(datetime.fromtimestamp(1572136200.0, tz)) # 2019-10-27 02:30:00+02:00
在包含时区的情况下,打印生成的 datetime
实例现在将包含偏移量,以显示时间实际上并不相同。
我建议使用arrow
包来处理始终包含时区(默认为操作系统时区)的日期和时间。
参考文献
本地化方法的文档 - https://github.com/stub42/pytz/blob/master/src/pytz/tzinfo.py#L258【讨论】:
感谢您的回答。这确实完全回答了这个评论。关于问题的第一部分,如何选择datetime.datetime.strptime("2019-10-27 02:30:00", '%Y-%m-%d %H:%M:%S')
的答案?实际上可能是两个日期时间
添加了有关本地化的注释以涵盖该内容。
嘿,默认为英国英语。固定。以上是关于在 DST 更改发生时将字符串解析为日期的主要内容,如果未能解决你的问题,请参考以下文章
如何比较 DST 与 Laravel / Carbon 更改时的日期