Kyf*_*rEz 1 python datetime pytz python-dateutil
我如何使用 dateutil.tz.tz.tzoffset 类型的对象来本地化具有正确时区和 DST 信息的时区原始日期时间对象,以便它可以正确转换为 UTC?或者,如何将 dateutil.tz.tz.tzoffset 转换为 pytz.timezone?
我一直无法找到有关使用 dateutil.tz.tz.tzoffset 对象本地化日期时间对象的好信息。请参阅下面的一些我审查过的更好的文章。
背景资料:
我正在处理大量日期字符串,其中大多数没有时区信息。在某些情况下,时间是格林威治标准时间,在其他情况下是本地时间。我必须首先确定创建这些各种日志的设备的时区,然后解析各种日期字符串,如果是本地时间,则添加添加时区,最后将其转换为 UTC。
我几乎让这一切都在工作,除了确定时区的唯一可靠方法是从文本文件中获取日期格式为 EDT、IST 等,因此我使用了以下链接中最高投票的帖子来完成这使用 dateutil 的 parser.parse() 函数并将其发送给它的 tzinfos 参数的字典。(在 Python 中使用时区缩写名称解析日期/时间字符串?)
但是,这给我留下了一个 DateTime,它有一个 tzinfo type=dateutil.tz.tz.tzoffset。我没问题,除非我需要使用这个 tzinfo 来本地化不包含时区信息的字符串,并且 dateutil.tz.tz.tzoffset 类型没有像 pytz.timezone 那样的本地化选项,这是关键我的问题。
我让这太难了吗?我是否只是用我保存的 dateutil.tz.tz.tzoffset 对象替换了时区天真日期时间中的 tzinfo ?
代码:
下面读取日期字符串并将其保存为日期时间对象,将时区保存在 var 中以备后用,然后将日期字符串转换为 UTC:
from dateutil.parser import parse as parsedate
import pytz
from pytz import timezone
from datetime import datetime
timestr = 'Sat, 5/01/2019 8:00PM EDT' #only reliable source of timezone info
dtfromstrEDT = parsedate(timestr, tzinfos=tzd) #tzd is created from the above link
mytimeZone = dtfromstrEDT.tzinfo # save local timezone
dtUTC = dtfromstrEDT.astimezone(pytz.timezone('UTC')) # convert to utc
Run Code Online (Sandbox Code Playgroud)
现在这是一个新的时区天真日期字符串。它是在与上面相同的本地时间(EDT)记录的,所以我想使用我保存的 mytimeZone var 来本地化它并转换为 UTC。我使用标准的 strptime 将它作为一个简单的日期时间读入。但是,当使用 mytimeZone 本地化 Naive 日期时间时,它失败了。错误如下。我理解错误;但我不知道如何完成我需要的:
timestrnaive = 'Mar 15 12:09:20 2019' #in EDT time, same as above string but without any timezone info
dtfromstrNaive = datetime.strptime(timestrnaive, "%b %d %H:%M:%S %Y")
dtlocalized = mytimeZone.localize(dtfromstrNaive, is_dst=True)
# the above is where it fails with provided error below
# however I can do this instead if I had a pytz.timezone object:
loc_tz = pytz.timezone('America/New_York')
dtlocalized = loc_tz.localize(dtfromstrNaive, is_dst=True)
dtUTC2 = dtlocalized.astimezone(pytz.timezone('UTC')) # convert to utc
Run Code Online (Sandbox Code Playgroud)
错误:
Traceback (most recent call last):
File "C:\Examples\timezones.py", line 221, in <module>
dtlocalized = mytimeZone.localize(dtfromstrNaive, is_dst=True) # convert to whatever tz is stored in self.timeZone
AttributeError: 'tzoffset' object has no attribute 'localize'
Run Code Online (Sandbox Code Playgroud)
审查了以下内容:
从时区偏移量本地化日期时间(时区感知) - 我不确定如何将其应用于此问题,因为我有一个 dateutil.tz.tz.tzoffset 对象,而不是原始 utc 时间。
在 Python 中解析带有时区缩写名称的日期/时间字符串?- 这让我可以读取时区数据,例如 EDT 和 PDT。
如何在 python 中识别不知道的日期时间时区- 这没有帮助,因为它没有解决我提到的 dateutil.tz.tz.tzoffset 问题。
您在这里存在的主要误解是您需要该localize方法,这是pytz从 PEP 495 添加“折叠”属性之前的时代开始的历史文物。你可以阅读更多的原因是pytz来自于标准库的接口偏离这篇文章。
正如你在你的答案注意,任何东西其他比pytz区,你可以简单地使用.replace来构建一个新的datetime与适当的时区。还有一个dateutil.utils.default_tzinfo方便的功能,它会自动检测日期时间是否幼稚,并为tzinfo如果是的话附加一个默认值。
需要注意的另一件事是,您pytz不需要使用here,因为dateutil还提供了一个UTC对象,因此您可以执行以下操作:
from dateutil import tz
timestrnaive = 'Mar 15 12:09:20 2019'
dtfromstrNaive = datetime.strptime(timestrnaive, "%b %d %H:%M:%S %Y")
dtlocalized = dtfromstrNaive.replace(tzinfo=mytimeZone)
dtUTC2 = dtlocalized.astimezone(tz.UTC) # Convert to UTC
Run Code Online (Sandbox Code Playgroud)
因此,您不需要对pytz.
如果你想了解更多关于在 Python 中使用时区的知识,我最近也在 PyCon 上做了一个演讲。