2010-07-22 93 views
101

我有一个使用IPDDump创建的黑莓IPD备份的CSV转储文件。 在这里的日期/时间字符串看起来像这样 (其中EST是澳大利亚时区):Python strptime()和时区?

Tue Jun 22 07:46:22 EST 2010 

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

>>> datetime.datetime.strptime('Tue Jun 22 12:10:20 2010 EST', '%a %b %d %H:%M:%S %Y %Z') 

然而,出于某种原因,该回来的datetime对象似乎不具有任何与之相关的tzinfo

我没读this page,显然datetime.strptime将丢弃tzinfo,但是,我查了资料,我无法找到任何记录here这种效果。

我已经能够使用第三方Python库dateutil获得解析日期,但是我仍然好奇我是如何错误地使用内置的strptime()?有没有办法让strptime()与时区一起玩?

+1

难道你不能...将所有日期转换为格林威治标准时间? – Robus 2010-07-22 02:48:42

+1

@Robus:嗯,我希望这样做 - 但我认为strftime/datetime可以以某种方式做到这一点?无论如何,我需要存储/解析日期时间位于EST时区的事实,或者它们发生在我身上的任何时区。该脚本需要能够解析具有时区信息的通用日期时间(例如,ETC可以是任何其他时区)。 – victorhooi 2010-07-22 03:00:15

+3

EST也是美国时区的缩写。 (同样,BST既是英国的也是巴西的时区缩写。)这样的缩写本质上是不明确的。相反,请使用相对于UTC/GMT的偏移量。 (如果需要支持缩写,则需要使映射区域依赖,并且这是一个凌乱的鼠洞。) – 2010-07-22 08:14:00

回答

26

datetime module documentation说:

Return a datetime corresponding to date_string, parsed according to format. This is equivalent to datetime(*(time.strptime(date_string, format)[0:6])) .

请参阅[0:6]?这让你(year, month, day, hour, minute, second)。没有其他的。没有提及时区。

有趣的是,[Win XP SP2,Python 2.6,2.7]将您的示例传递给time.strptime不起作用,但是如果剥离“%Z”和“EST”,它确实有效。也使用“UTC”或“GMT”而不是“EST”的作品。 “PST”和“MEZ”不起作用。令人费解。

+2

相关Python错误:[strptime中的%Z与EST等不匹配] (http://bugs.python.org/issue22377) – jfs 2014-09-29 12:11:52

276

我推荐使用python-dateutil。它的解析器已经能够解析我迄今为止所引用的每个日期格式。

>>> 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) 

等。没有处理strptime()格式废话...只是在它的日期,它是正确的事情。

更新:糟糕。我错过了你原来的问题,你提到你使用dateutil,抱歉。但是我希望这个答案对其他遇到这个问题的人来说仍然有用,因为他们有日期分析问题并查看该模块的实用程序。

+5

一百万,一个赞扬这个令人难以置信的类。感谢你的分享。 – 2012-06-11 04:03:24

+1

+1这个答案已被证明非常有用!谢谢:-) – nemesisdesign 2012-11-18 19:43:22

+0

鉴于如此多的人倾向于使用python-dateutil,我想指出我们对该lib的一个限制。 >>> parser.parse(“Thu,25 Sep 2003 10:49:41,123 -0300”) Traceback(最近呼叫最后一个): 文件“”,第1行,在 文件“/ Users/wanghq /awscli/lib/python2.7/site-packages/dateutil/parser.py“,第748行,解析为 返回DEFAULTPARSER.parse(timestr,** kwargs) 文件”/ Users/wanghq/awscli/lib/python2 .7/site-packages/dateutil/parser.py“,第310行,在解析res,skipped_tokens = self._parse(timestr,** kwargs) TypeError:'NoneType'对象不可迭代 – wanghq 2014-04-29 00:16:39

6

您的时间字符串与rfc 2822 (date format in email, http headers)中的时间格式类似。你可以只用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) 

看得出来产生时区感知datetime对象的各种版本的Python解决方案:parsing date with timezone from an email

在这种格式下,EST is semantically equivalent to -0500。虽然,一般来说,a timezone abbreviation is not enough, to identify a timezone uniquely