如何在Python中解析带时区缩写的日期/时间字符串?
我正在尝试在Python中解析像 "Sat, 11/01/09 8:00PM EST"
这样的时间戳字符串,但我发现很难找到一个能处理缩写时区的解决方案。
我正在使用 dateutil
的 parse()
函数,但它无法解析时区。有没有简单的方法可以做到这一点?
6 个回答
你可以试试 pytz 模块:http://pytz.sourceforge.net/
pytz 是一个可以把 Olson 时区数据库引入到 Python 中的库。这个库可以让你在 Python 2.3 或更高版本中进行准确的跨平台时区计算。它还解决了夏令时结束时出现的时间模糊问题,关于这个问题你可以在 Python 库参考文档(datetime.tzinfo)中了解更多。
几乎所有的 Olson 时区都得到了支持。
dateutil
库里的 parser.parse()
方法可以接受一个叫 tzinfos
的参数,这个参数是一个字典,格式像这样 {'EST': -5*3600}
(也就是说,把时区名称和格林威治标准时间的偏移量用秒表示对应起来)。假设我们有这样的字典,我们可以这样使用:
>>> import dateutil.parser as dp
>>> s = 'Sat, 11/01/09 8:00PM'
>>> for tz_code in ('PST','PDT','MST','MDT','CST','CDT','EST','EDT'):
>>> dt = s+' '+tz_code
>>> print dt, '=', dp.parse(dt, tzinfos=tzd)
Sat, 11/01/09 8:00PM PST = 2009-11-01 20:00:00-08:00
Sat, 11/01/09 8:00PM PDT = 2009-11-01 20:00:00-07:00
Sat, 11/01/09 8:00PM MST = 2009-11-01 20:00:00-07:00
Sat, 11/01/09 8:00PM MDT = 2009-11-01 20:00:00-06:00
Sat, 11/01/09 8:00PM CST = 2009-11-01 20:00:00-06:00
Sat, 11/01/09 8:00PM CDT = 2009-11-01 20:00:00-05:00
Sat, 11/01/09 8:00PM EST = 2009-11-01 20:00:00-05:00
Sat, 11/01/09 8:00PM EDT = 2009-11-01 20:00:00-04:00
关于 tzinfos
的内容,这里是我怎么填充我的字典的:
tz_str = '''-12 Y
-11 X NUT SST
-10 W CKT HAST HST TAHT TKT
-9 V AKST GAMT GIT HADT HNY
-8 U AKDT CIST HAY HNP PST PT
-7 T HAP HNR MST PDT
-6 S CST EAST GALT HAR HNC MDT
-5 R CDT COT EASST ECT EST ET HAC HNE PET
-4 Q AST BOT CLT COST EDT FKT GYT HAE HNA PYT
-3 P ADT ART BRT CLST FKST GFT HAA PMST PYST SRT UYT WGT
-2 O BRST FNT PMDT UYST WGST
-1 N AZOT CVT EGT
0 Z EGST GMT UTC WET WT
1 A CET DFT WAT WEDT WEST
2 B CAT CEDT CEST EET SAST WAST
3 C EAT EEDT EEST IDT MSK
4 D AMT AZT GET GST KUYT MSD MUT RET SAMT SCT
5 E AMST AQTT AZST HMT MAWT MVT PKT TFT TJT TMT UZT YEKT
6 F ALMT BIOT BTT IOT KGT NOVT OMST YEKST
7 G CXT DAVT HOVT ICT KRAT NOVST OMSST THA WIB
8 H ACT AWST BDT BNT CAST HKT IRKT KRAST MYT PHT SGT ULAT WITA WST
9 I AWDT IRKST JST KST PWT TLT WDT WIT YAKT
10 K AEST ChST PGT VLAT YAKST YAPT
11 L AEDT LHDT MAGT NCT PONT SBT VLAST VUT
12 M ANAST ANAT FJT GILT MAGST MHT NZST PETST PETT TVT WFT
13 FJST NZDT
11.5 NFT
10.5 ACDT LHST
9.5 ACST
6.5 CCT MMT
5.75 NPT
5.5 SLT
4.5 AFT IRDT
3.5 IRST
-2.5 HAT NDT
-3.5 HNT NST NT
-4.5 HLV VET
-9.5 MART MIT'''
tzd = {}
for tz_descr in map(str.split, tz_str.split('\n')):
tz_offset = int(float(tz_descr[0]) * 3600)
for tz_code in tz_descr[1:]:
tzd[tz_code] = tz_offset
顺便说一下,根据 @Hank Gay 的说法,时区的命名并没有明确的定义。为了制作我的表格,我使用了这个网站和这个维基百科页面。我查看了每个冲突,并在不常用的名称和常用名称之间做了选择,倾向于使用更常用的名称。有一个例外 - IST - 这个就不太好判断(它可以指代 印度标准时间、伊朗标准时间、爱尔兰标准时间 或 以色列标准时间),所以我把它从表格中省略了 - 你可能需要根据你所在的位置来决定要添加什么。哦,还有,我把基里巴斯共和国的那些奇怪的“看我,我是第一个庆祝新年的” GMT+13 和 GMT+14 时区也省略掉了。
这可能行不通,因为这些缩写并不是独一无二的。你可以查看这个页面了解更多细节。如果你处理的是一组已知的输入,可能最终还是得自己手动处理。