Analyse de la chaîne de date/heure avec le nom abrégé du fuseau horaire en Python?

J'essaie d'analyser les chaînes d'horodatage comme "Sat, 11/01/09 8:00PM EST" en Python, mais j'ai du mal à trouver une solution qui gérera le fuseau horaire abrégé.

J'utilise dateutil'S parse() fonction, mais il n'analyse pas le fuseau horaire. Est-il un moyen facile de faire cela?

29
demandé sur marcog 2009-11-09 23:26:32

5 réponses

Cela ne fonctionnera probablement pas parce que ces abréviations ne sont pas uniques. Voir cette page pour plus de détails. Vous pourriez finir par devoir le gérer manuellement vous-même si vous travaillez avec un ensemble d'entrées connu.

11
répondu Hank Gay 2009-11-09 20:32:51

dateutil's parser.parse() accepte comme argument de mot-clé tzinfos un dictionnaire du type {'EST': -5*3600} (c'est-à-dire, faisant correspondre le nom de la zone au décalage GMT en secondes). Donc, en supposant que nous avons que nous pouvons faire:

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

En ce qui concerne le contenu de tzinfos, Voici comment j'ai rempli le mien:

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. par @ Hank gay fuseau horaire nommage n'est pas clairement défini. Pour former ma table, j'ai utilisé http://www.timeanddate.com/library/abbreviations/timezones/ et http://en.wikipedia.org/wiki/List_of_time_zone_abbreviations . J'ai regardé chaque conflit et résolu les conflits entre les noms obscurs et populaires vers les noms populaires (plus utilisés). Il y en avait un - IST - qui n'était pas aussi clair (cela peut signifier Heure normale indienne, Heure Normale de L'Iran, Irish Standard Time or Israel Standard Time ), donc je l'ai laissé hors de la table - vous devrez peut-être choisir ce qu'il faut ajouter en fonction de votre emplacement. Oh-et j'ai laissé de côté la République de Kiribati avec leur absurde "Regardez-moi, je suis le premier à célébrer le Nouvel An" GMT+13 et GMT+14 fuseaux horaires.

57
répondu Nas Banov 2011-03-22 08:31:43

Vous pouvez essayer le module pytz: http://pytz.sourceforge.net/

Pytz apporte la base de données Olson tz dans Python. Cette bibliothèque permet de précis et fuseau horaire multiplateforme calculs utilisant Python 2.3 ou supérieur. Il résout également la question de temps Ambigus à la fin de la lumière du jour économies, que vous pouvez en savoir plus sur dans la référence de la bibliothèque Python (datetime.tzinfo).

Amost tous les fuseaux horaires D'Olson sont soutenu.

9
répondu Drake Guan 2011-01-23 12:55:09

La fonction parse() dans dateutil ne peut pas gérer les fuseaux horaires. La chose que j'ai utilisée est le formateur %Z et l'heure.fonction strptime (). Je n'ai aucune idée de comment il traite de l'ambiguïté dans les fuseaux horaires, mais il semble faire la différence entre CDT et CST, ce qui est tout ce dont j'avais besoin.

Contexte: je stocke des images de sauvegarde dans des répertoires dont les noms sont des horodatages en utilisant l'heure locale, car je n'ai pas d'horloges GMT à portée de main à la maison. J'ai donc utiliser le temps.strptime(d, R" % Y - % m - % dT % H: % M: % S_ % Z") à analysez les noms de répertoire dans un temps réel pour l'analyse de l'âge.

5
répondu Mike DeSimone 2009-11-09 21:49:44

J'ai utilisé pytz pour générer un TZINFOS cartographie:

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 l'Utilisation de

>>> 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 l'Utilisation de

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

La conversion UTC est nécessaire car il y a beaucoup de fuseaux horaires disponibles pour chaque abréviation. Depuis TZINFOS est un dict, il n'a que le dernier fuseau horaire par abréviation. Et vous ne pouvez pas obtenir celui que vous attendiez avant de conversion.

>>> tzdate
datetime.datetime(2009, 11, 1, 20, 0, tzinfo=tzfile('/usr/share/zoneinfo/America/Port-au-Prince'))
0
répondu reubano 2017-03-27 09:19:30