簡體   English   中英

在 Python 中解析帶有時區縮寫名稱的日期/時間字符串?

[英]Parsing date/time string with timezone abbreviated name in Python?

我正在嘗試在 Python 中解析諸如"Sat, 11/01/09 8:00PM EST"類的時間戳字符串,但我無法找到可以處理縮寫時區的解決方案。

我正在使用dateutilparse()函數,但它不解析時區。 是否有捷徑可尋?

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

附: 每個@Hank Gay 時區命名沒有明確定義。 為了形成我的表格,我使用了http://www.timeanddate.com/library/abbreviations/timezones/http://en.wikipedia.org/wiki/List_of_time_zone_abbreviations 我查看了每個沖突,並解決了晦澀難懂的名字和流行名字之間的沖突(更常用的名字)。 有一個 - IST - 沒有那么明確(它可能意味着印度標准時間伊朗標准時間愛爾蘭標准時間以色列標准時間),所以我把它排除在表之外 - 你可能需要選擇要添加的內容因為它基於您的位置。 哦 - 我遺漏了基里巴斯共和國他們荒謬的“看看我,我是第一個慶祝新年的人”GMT+13 和 GMT+14 時區。

這可能行不通,因為這些縮寫不是唯一的。 有關詳細信息,請參閱此頁面 如果您使用一組已知的輸入,您可能最終只需要自己手動處理它。

您可以嘗試 pytz 模塊: http ://pytz.sourceforge.net/

pytz 將 Olson tz 數據庫引入 Python。 該庫允許使用 Python 2.3 或更高版本進行准確的跨平台時區計算。 它還解決了夏令時結束時時間不明確的問題,您可以在 Python 庫參考 (datetime.tzinfo) 中閱讀更多相關信息。

支持幾乎所有的奧爾森時區。

dateutil 中的 parse() 函數無法處理時區。 我一直在使用的是 %Z 格式化程序和 time.strptime() 函數。 我不知道它如何處理時區的歧義,但它似乎說明了 CDT 和 CST 之間的區別,這正是我所需要的。

背景:我將備份圖像存儲在名稱為使用本地時間的時間戳的目錄中,因為我家里沒有 GMT 時鍾。 所以我使用 time.strptime(d, r"%Y-%m-%dT%H:%M:%S_%Z") 將目錄名稱解析回實際時間進行年齡分析。

我使用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 轉換,因為每個縮寫都有許多可用的時區。 由於TZINFOS是一個dict ,它只有每個縮寫的最后一個時區。 而且您可能無法獲得您期望的轉換前的內容。

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

我意識到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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM