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

时间:2009-11-09 20:26:32

标签: python date timezone

我正在尝试解析Python中的"Sat, 11/01/09 8:00PM EST"时间戳字符串,但我找不到能够处理缩写时区的解决方案。

我正在使用dateutilparse()函数,但它不会解析时区。有一个简单的方法吗?

6 个答案:

答案 0 :(得分:59)

dateutil的{​​{1}}接受关键字参数parser.parse()作为tzinfos种类的字典(即,将区域名称与GMT偏移量匹配,以秒为单位)。所以假设我们有,我们可以这样做:

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

PS。 @Hank Gay时区命名没有明确定义。为了形成我的表格,我使用了http://www.timeanddate.com/library/abbreviations/timezones/http://en.wikipedia.org/wiki/List_of_time_zone_abbreviations。我查看了每个冲突,并解决了流行的(更常用的)晦涩和流行的名字之间的冲突。有一个 - IST - 不是那么明确(它可能意味着印度标准时间伊朗标准时间爱尔兰标准时间以色列标准时间),所以我将其排除在表格之外 - 您可能需要根据您的位置选择要添加的内容。哦 - 我和他们荒谬的“看着我,我是第一个庆祝新年”GMT + 13和GMT + 14时区,遗漏了基里巴斯共和国。

答案 1 :(得分:11)

这可能不会起作用,因为这些缩写并不是唯一的。有关详细信息,请参阅this page。如果你正在处理一组已知的输入,你可能需要自己手动处理它。

答案 2 :(得分:10)

您可以尝试使用pytz模块:http://pytz.sourceforge.net/

  

pytz带来了Olson tz数据库   蟒蛇。这个库允许准确   和跨平台时区   使用Python 2.3或   更高。它也解决了这个问题   在白昼结束时的模糊时期   储蓄,你可以阅读更多   在Python Library Reference中   (datetime.tzinfo)。

     

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

答案 3 :(得分:5)

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

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

答案 4 :(得分:1)

我使用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')}

parser用法

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

由于每个缩写都有许多时区,因此需要进行UTC转换。由于TZINFOSdict,因此每个缩写只包含最后一个时区。而且你可能得不到你预期转换的那个。

>>> tzdate
datetime.datetime(2009, 11, 1, 20, 0, tzinfo=tzfile('/usr/share/zoneinfo/America/Port-au-Prince'))

答案 5 :(得分:1)

我意识到dateparser可以解决此问题。 https://pypi.org/project/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

此库支持的其他时区:https://github.com/scrapinghub/dateparser/blob/e11a18a4d183a14211b28f5927ce01b220335881/dateparser/timezones.py