在Python中解析带有时区缩写名称的日期/时间字符串?

在Python中解析带有时区缩写名称的日期/时间字符串?,python,date,timezone,Python,Date,Timezone,我试图在Python中解析时间戳字符串,如“Sat,11/01/09 8:00PM EST”,但我很难找到处理缩短时区的解决方案 我使用的是的parse()函数,但它不解析时区。有没有一种简单的方法可以做到这一点?这可能行不通,因为这些缩写不是唯一的。有关详细信息,请参阅。如果您使用的是一组已知的输入,那么您可能需要自己手动处理它。dateutil中的parse()函数无法处理时区。我一直在使用的是%Z格式化程序和time.strtime()函数。我不知道它是如何处理时区中的模糊性的,但它似乎能

我试图在Python中解析时间戳字符串,如
“Sat,11/01/09 8:00PM EST”
,但我很难找到处理缩短时区的解决方案


我使用的是的
parse()
函数,但它不解析时区。有没有一种简单的方法可以做到这一点?

这可能行不通,因为这些缩写不是唯一的。有关详细信息,请参阅。如果您使用的是一组已知的输入,那么您可能需要自己手动处理它。

dateutil中的parse()函数无法处理时区。我一直在使用的是%Z格式化程序和time.strtime()函数。我不知道它是如何处理时区中的模糊性的,但它似乎能说明CDT和CST之间的区别,这正是我所需要的


背景:我将备份映像存储在目录中,其名称是使用本地时间的时间戳,因为我家里没有GMT时钟。因此,我使用time.strtime(d,r“%Y-%m-%dT%H:%m:%S_%Z”)将目录名解析回实际时间进行年龄分析。

dateutil
parser.parse()
接受作为关键字参数的
tzinfos
一种字典
{EST':-5*3600}
(也就是说,将区域名与GMT的偏移量以秒为单位进行匹配)。因此,假设我们有这些,我们可以:

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

ps.@Hank Gay时区命名未明确定义。为了组成我的桌子,我使用了和。我查看了每个冲突,并解决了晦涩和流行名称与流行名称(更常用名称)之间的冲突。有一个-IST-没有那么明确(它可能意味着印度标准时间、伊朗标准时间、爱尔兰标准时间或以色列标准时间),所以我把它从表中删除了-您可能需要根据您的位置选择要添加的内容。哦-我用他们荒谬的“看着我,我是第一个庆祝新年”把基里巴斯共和国排除在外,GMT+13和GMT+14时区。

你可以试试pytz模块:

pytz将Olson tz数据库引入 python这个库允许精确的 跨平台时区 使用Python 2.3或 较高的。它还解决了 白天结束时的模糊时间 储蓄,您可以阅读更多有关储蓄的信息 在Python库参考中 (datetime.tzinfo)

几乎所有的奥尔森时区都是 支持


我使用
pytz
生成
TZINFOS
映射:

from datetime import datetime as dt

import pytz

from dateutil.tz import gettz
from pytz import utc
from dateutil import parser


def gen_tzinfos():
    for zone in pytz.common_timezones:
        try:
            tzdate = pytz.timezone(zone).localize(dt.utcnow(), is_dst=None)
        except pytz.NonExistentTimeError:
            pass
        else:
            tzinfo = gettz(zone)

            if tzinfo:
                yield tzdate.tzname(), tzinfo
TZINFOS
用法

>>> TZINFOS = dict(gen_tzinfos())
>>> TZINFOS
{'+02': tzfile('/usr/share/zoneinfo/Antarctica/Troll'),
 '+03': tzfile('/usr/share/zoneinfo/Europe/Volgograd'),
 '+04': tzfile('Europe/Ulyanovsk'),
 '+05': tzfile('/usr/share/zoneinfo/Indian/Kerguelen'),              
...
 'WGST': tzfile('/usr/share/zoneinfo/America/Godthab'),
 'WIB': tzfile('/usr/share/zoneinfo/Asia/Pontianak'),
 'WIT': tzfile('/usr/share/zoneinfo/Asia/Jayapura'),
 'WITA': tzfile('/usr/share/zoneinfo/Asia/Makassar'),
 'WSDT': tzfile('/usr/share/zoneinfo/Pacific/Apia'),
 'XJT': tzfile('/usr/share/zoneinfo/Asia/Urumqi')}
>>> date_str = 'Sat, 11/01/09 8:00PM EST'
>>> tzdate = parser.parse(date_str, tzinfos=TZINFOS)
>>> tzdate.astimezone(utc)
datetime.datetime(2009, 11, 2, 1, 0, tzinfo=<UTC>)
解析器
用法

>>> TZINFOS = dict(gen_tzinfos())
>>> TZINFOS
{'+02': tzfile('/usr/share/zoneinfo/Antarctica/Troll'),
 '+03': tzfile('/usr/share/zoneinfo/Europe/Volgograd'),
 '+04': tzfile('Europe/Ulyanovsk'),
 '+05': tzfile('/usr/share/zoneinfo/Indian/Kerguelen'),              
...
 'WGST': tzfile('/usr/share/zoneinfo/America/Godthab'),
 'WIB': tzfile('/usr/share/zoneinfo/Asia/Pontianak'),
 'WIT': tzfile('/usr/share/zoneinfo/Asia/Jayapura'),
 'WITA': tzfile('/usr/share/zoneinfo/Asia/Makassar'),
 'WSDT': tzfile('/usr/share/zoneinfo/Pacific/Apia'),
 'XJT': tzfile('/usr/share/zoneinfo/Asia/Urumqi')}
>>> date_str = 'Sat, 11/01/09 8:00PM EST'
>>> tzdate = parser.parse(date_str, tzinfos=TZINFOS)
>>> tzdate.astimezone(utc)
datetime.datetime(2009, 11, 2, 1, 0, tzinfo=<UTC>)

我意识到,
dateparser
可以解决这个问题

用法:

import dateparser


def time_gmt_format(str_datetime):
    # from string like "29/05/2020, 08:18 WIB" to GMT yyyymmddhhmmss

    date_time_obj = dateparser.parse(str_datetime, date_formats=['%d/%m/%Y, %H:%M %Z'], 
    settings={'TO_TIMEZONE': 'GMT'})  # convert to GMT datetime object

    return date_time_obj.strftime('%Y%m%d%H%M%S')  # Output: 20200529011800


此库支持的其他时区:

如果我们将其限制在美国的时区,是否会变得更容易?在这种情况下,有一套“标准”的缩写吗?别忘了“美国时区”包括AKST、AKDT、HAST和HADT。如果你只是指大陆上的48个州,那么你只需要处理8个3字母的时区(4个时区、标准和夏令时)。显然,为了更好地衡量,有些地方使用HST和HDT作为HAST和HADT的等价物=\迄今为止最简单的路线(虽然通常不是最实用的)是调整提供数据的任何程序,使其以UTC发送数据,或使用UTC的偏移量发送数据,或使用zoneinfo数据库中的完整、有效时区发送数据。我很好奇,如何用said pytz解析“Sat,11/01/09 8:00PM EST”?老实说,这是无法解决的,因为缩写不是一对一的。好消息是pytz已经提供了映射(一对多),留给程序员选择所需的映射。@NasBanov:“EST”不明确,但我无法开始工作。小写的h似乎会引起问题。我不得不在时区列表中使用大写的CHST,并进行
dp.parse(dt,tzinfos=tzd)
字典不正确,例如,2012/12年的MSK有4个小时的偏移量,但前一年只有3个小时。注意:
MSK
将在2014年10月26日再次距UTC 3个小时,即。,给定
'MSK'
如果不知道日期,则无法返回正确的UTC偏移量。这就是我所寻找的。IST更常用作印度标准时间(UTC+5:30)。据我所知,strptime只接受当前时区设置中给定的时间来处理模糊性。python bug tracker中提出了一个问题: