Python strtime()和时区?

Python strtime()和时区?,python,datetime,timezone,Python,Datetime,Timezone,我有一个来自Blackberry IPD备份的CSV转储文件,使用IPDDump创建。 这里的日期/时间字符串如下所示 (其中,EST是澳大利亚时区): 我需要能够用Python解析这个日期。起初,我尝试使用datettime中的strtime()函数 >>> datetime.datetime.strptime('Tue Jun 22 12:10:20 2010 EST', '%a %b %d %H:%M:%S %Y %Z') 但是,由于某种原因,返回的datetime对象

我有一个来自Blackberry IPD备份的CSV转储文件,使用IPDDump创建。 这里的日期/时间字符串如下所示 (其中,
EST
是澳大利亚时区):

我需要能够用Python解析这个日期。起初,我尝试使用datettime中的
strtime()
函数

>>> datetime.datetime.strptime('Tue Jun 22 12:10:20 2010 EST', '%a %b %d %H:%M:%S %Y %Z')
但是,由于某种原因,返回的
datetime
对象似乎没有任何与之关联的
tzinfo

我确实读过那篇显然是
datetime.strtime
默默地丢弃
tzinfo
,但是,我检查了文档,我找不到任何有这种效果的文档

我已经能够使用第三方Python库解析日期,但是我仍然对如何错误地使用内置的
strtime()
感到好奇?有什么方法可以让strtime()更好地使用时区吗?

上面说:

返回与date_字符串相对应的datetime,根据格式进行分析。这相当于
datetime(*(time.strtime(日期字符串,格式)[0:6]))

看到了吗?这让你
(年、月、日、时、分、秒)
。没有别的了。没有提到时区

有趣的是,[winxpsp2,python2.6,2.7]将示例传递给
time.strtime
不起作用,但是如果去掉“%Z”和“EST”,它确实起作用。使用“UTC”或“GMT”而不是“EST”也有效。“PST”和“MEZ”不起作用。令人费解

值得注意的是,此版本已从3.2版开始更新,同一文档现在还声明了以下内容:

将%z指令提供给strtime()方法时,将生成aware datetime对象。结果的tzinfo将设置为时区实例

请注意,这不适用于%Z,因此案例很重要。请参见以下示例:

In [1]: from datetime import datetime

In [2]: start_time = datetime.strptime('2018-04-18-17-04-30-AEST','%Y-%m-%d-%H-%M-%S-%Z')

In [3]: print("TZ NAME: {tz}".format(tz=start_time.tzname()))
TZ NAME: None

In [4]: start_time = datetime.strptime('2018-04-18-17-04-30-+1000','%Y-%m-%d-%H-%M-%S-%z')

In [5]: print("TZ NAME: {tz}".format(tz=start_time.tzname()))
TZ NAME: UTC+10:00
我建议使用。到目前为止,它的解析器能够解析我抛出的所有日期格式

>>> from dateutil import parser
>>> parser.parse("Tue Jun 22 07:46:22 EST 2010")
datetime.datetime(2010, 6, 22, 7, 46, 22, tzinfo=tzlocal())
>>> parser.parse("Fri, 11 Nov 2011 03:18:09 -0400")
datetime.datetime(2011, 11, 11, 3, 18, 9, tzinfo=tzoffset(None, -14400))
>>> parser.parse("Sun")
datetime.datetime(2011, 12, 18, 0, 0)
>>> parser.parse("10-11-08")
datetime.datetime(2008, 10, 11, 0, 0)
等等。不要处理
strtime()
格式错误。。。只要给它一个约会,它就会做正确的事情


更新:哎呀。我在你的原始问题中遗漏了你提到你使用了
dateutil
,对此我深表歉意。但我希望这个答案对其他人仍然有用,他们在遇到日期解析问题时偶然发现了这个问题,并看到了该模块的实用性。

您的时间字符串与中的时间格式类似。您可以仅使用stdlib解析它:

>>> from email.utils import parsedate_tz
>>> parsedate_tz('Tue Jun 22 07:46:22 EST 2010')
(2010, 6, 22, 7, 46, 22, 0, 1, -1, -18000)
请参阅为各种Python版本生成时区感知datetime对象的解决方案:


在此格式中。不过,总的来说,.

遇到了这个问题

我最终做了什么:

# starting with date string
sdt = "20190901"
std_format = '%Y%m%d'

# create naive datetime object
from datetime import datetime
dt = datetime.strptime(sdt, sdt_format)

# extract the relevant date time items
dt_formatters = ['%Y','%m','%d']
dt_vals = tuple(map(lambda formatter: int(datetime.strftime(dt,formatter)), dt_formatters))

# set timezone
import pendulum
tz = pendulum.timezone('utc')

dt_tz = datetime(*dt_vals,tzinfo=tz)

由于
strtime
返回一个具有
tzinfo
属性的datetime对象,我们只需将其替换为所需的时区即可

>>> import datetime

>>> date_time_str = '2018-06-29 08:15:27.243860'
>>> date_time_obj = datetime.datetime.strptime(date_time_str, '%Y-%m-%d %H:%M:%S.%f').replace(tzinfo=datetime.timezone.utc)
>>> date_time_obj.tzname()
'UTC'

你就不能。。。将所有日期转换为格林尼治标准时间?@Robus:嗯,我希望这样做,但我假设strftime/datetime可以以某种方式做到这一点?不管是哪种方式,我都需要存储/解析datetimes在EST时区或发生在我身上的任何时区的事实。该脚本需要能够解析带有时区信息的通用日期时间(例如,ETC可以是任何其他时区)。EST也是美国时区的缩写。(类似地,BST既是英国时区又是巴西时区缩写。)这些缩写本身就是模棱两可的。使用相对于UTC/GMT的偏移。(如果需要支持缩写,则需要使映射区域设置依赖,这是一个混乱的漏洞。)。另请参见:鉴于有这么多人倾向于使用python dateutil,我想指出该库的一个局限性<代码>>>>parser.parse(“Thu,2003年9月25日10:49:41123-0300”)回溯(最近一次调用):文件“/Users/wanghq/awscli/lib/python2.7/site packages/dateutil/parser.py”第748行,在parse中返回DEFAULTPARSER.parse(timestr,**kwargs)文件“/Users/wanghq/awscli/lib/python2.7/site packages/dateutil/parser.py”,parse res中的第310行跳过了_tokens=self。_parse(timestr,**kwargs)TypeError:“NoneType”对象不可写@wanghq您需要用句点替换最后一个逗号。然后
parser.parse(“Thu,2003年9月25日10:49:41.123-0300”)返回:datetime(2003,9,25,10,49,41123000,tzinfo=tzoffset(None,-10800))
@flyingfoxlee,是的,我理解。我只想告诉人们python dateutil的局限性。它有神奇的功能,但有时无法做到。所以“只要向它抛出一个日期,它就会做正确的事情。”这不是100%正确的。
dateutil.parser.parse()2016年10月27日上午9:06(PDT))
返回:
datetime.datetime(2016,10,27,9,6)
无法计算时区…这取决于一个人的目标。
dateutil解析器
可能简单易用,但
strtime()
更快。此外,它的格式很容易学习。相关的Python错误:并非所有的时间戳字符串都是基于UTC的(例如,问题中的那个)。
>>> import datetime

>>> date_time_str = '2018-06-29 08:15:27.243860'
>>> date_time_obj = datetime.datetime.strptime(date_time_str, '%Y-%m-%d %H:%M:%S.%f').replace(tzinfo=datetime.timezone.utc)
>>> date_time_obj.tzname()
'UTC'