我有 YMD hms 格式的字符串,其中时区被剥离。但我知道他们是在夏令时的东部时间。
一种可移植的方式是使用pytz:
#!/usr/bin/env python
from datetime import datetime
import pytz # $ pip install pytz
naive_dt = datetime.strptime('2015-04-20 21:12:07', '%Y-%m-%d %H:%M:%S')
tz = pytz.timezone('US/Eastern')
eastern_dt = tz.normalize(tz.localize(naive_dt))
print(eastern_dt)
# -> 2015-04-20 21:12:07-04:00
我正在尝试将它们转换为 UTC 时间的纪元时间戳。
timestamp = (eastern_dt - datetime(1970, 1, 1, tzinfo=pytz.utc)).total_seconds()
# -> 1429578727.0
见Converting datetime.date to UTC timestamp in Python。
您的代码中有多个问题:
time.mktime() 可能会在输入时间不明确时返回错误结果(50% 的可能性),例如在秋季的“回退”DST 过渡期间
如果time.mktime() 和datetime.fromtimestamp() 无法访问系统(尤其是 Windows)上的历史时区数据库,则它们可能会在过去/未来日期失败
localize(dt) 可能会在不明确或不存在的时间(即 DST 转换期间)返回错误结果。如果您知道时间对应于夏令时,请使用is_dst=True。 tz.normalize() 在这里是必要的,以调整输入中可能不存在的时间
utc_dt.strftime("%s") is not portable and it does not respect tzinfo object。它将输入解释为本地时间,即,除非您的本地时区是 UTC,否则它会返回错误的结果。
我可以一直设置 is_dst=True 吗?
如果您不介意在模糊或不存在的时间获得不精确的结果,例如,美国/纽约时区的秋季有 DST 转换,您可以:
>>> from datetime import datetime
>>> import pytz # $ pip install pytz
>>> tz = pytz.timezone('America/New_York')
>>> ambiguous_time = datetime(2015, 11, 1, 1, 30)
>>> time_fmt = '%Y-%m-%d %H:%M:%S%z (%Z)'
>>> tz.localize(ambiguous_time).strftime(time_fmt)
'2015-11-01 01:30:00-0500 (EST)'
>>> tz.localize(ambiguous_time, is_dst=False).strftime(time_fmt) # same
'2015-11-01 01:30:00-0500 (EST)'
>>> tz.localize(ambiguous_time, is_dst=True).strftime(time_fmt) # different
'2015-11-01 01:30:00-0400 (EDT)'
>>> tz.localize(ambiguous_time, is_dst=None).strftime(time_fmt)
Traceback (most recent call last):
...
pytz.exceptions.AmbiguousTimeError: 2015-11-01 01:30:00
时钟倒转at 2a.m. on the first Sunday in November:
is_dst消歧标志可能有三个值:
-
False -- 默认,假设是冬季时间
-
True -- 假设是夏季时间
-
None -- 为不明确/不存在的时间引发异常。
is_dst 值对于现有的唯一当地时间将被忽略。
这是来自PEP 0495 -- Local Time Disambiguation 的图表,说明了 DST 转换:
当地时间在折叠中重复两次(夏季时间 - 折叠之前,冬季时间 - 折叠之后)。
为了能够自动消除当地时间的歧义,您需要一些额外的信息,例如,如果您阅读了一系列当地时间,那么如果您知道它们已排序可能会有所帮助:Parsing of Ordered Timestamps in Local Time (to UTC) While Observing Daylight Saving Time。