web-dev-qa-db-fra.com

Directive '% z' du fuseau horaire Python pour datetime.strptime () non disponible

Utilisation du modèle '% z' de datetime.strptime ()

J'ai une chaîne de texte qui représente une date et je suis parfaitement capable de l'analyser et de la transformer en un objet datetime propre:

date = "[24/Aug/2014:17:57:26"
dt = datetime.strptime(date, "[%d/%b/%Y:%H:%M:%S")  

Sauf que je ne peux pas attraper toute la chaîne de date avec le fuseau horaire en utilisant le % z motif comme spécifié ici

date_tz = 24/Aug/2014:17:57:26 +0200
dt = datetime.strptime(date, "[%d/%b/%Y:%H:%M:%S %z]")
>>> ValueError: 'z' is a bad directive in format '[%d/%b/%Y:%H:%M:%S %z]'

Parce que comme ce rapport de bogue dit 

strftime () est implémenté par plate-forme

Je précise que la directive naïve tzinfo '% Z' ne pose pas de problème

Solution de contournement: conversion de la chaîne tzinfo en objet tzinfo

Je peux parfaitement faire la solution suivante en transformant la chaîne de format d'heure GST en un objet tzinfo [comme suggéré ici] [4] en utilisant dateutil module Puis en insérant tzinfo dans l'objet datetime

Question: Rendre% z disponible pour ma plateforme?

Mais comme je vais évidemment avoir besoin du motif% z pour un projet ultérieur, j'aimerais trouver une solution pour éviter cette solution de contournement et utiliser un module externe pour cette tâche simple .. Pouvez-vous me suggérer de le lire? J'ai supposé que la version plus récente de python (je suis sur la version 2.7) peut le gérer, mais je préfère ne pas changer ma version maintenant pour ce détail petit mais crucial.

[MODIFIER]

Bien, voir les commentaires me fait reformuler ma question, comment analyser l'indicateur de fuseau horaire de messagerie à l'aide de strptime () sans connaître l'heure locale?

16
c24b

strptime() est implémenté en Python pur . Contrairement à strftime(); il [quelles directives sont supportées] ne dépend pas de la plateforme. %z est supporté depuis Python 3.2:

>>> from datetime import datetime
>>> datetime.strptime('24/Aug/2014:17:57:26 +0200', '%d/%b/%Y:%H:%M:%S %z')
datetime.datetime(2014, 8, 24, 17, 57, 26, tzinfo=datetime.timezone(datetime.timedelta(0, 7200)))

comment analyser l'indicateur de fuseau horaire de messagerie à l'aide de strptime () sans connaître l'heure locale?

Il n’ya pas d’implémentation concrète de fuseau horaire dans Python 2.7. Vous pouvez facilement implémenter l’analyse de décalage UTC, voir Comment analyser les dates avec -0400 chaîne de fuseau horaire en python?

20
jfs

Dans la réponse à @ j-f-sebastians, voici un correctif pour python 2.7

À la place d'utiliser:

datetime.strptime(t,'%Y-%m-%dT%H:%M %z')

utilisez la timedelta pour prendre en compte le fuseau horaire, comme ceci:

from datetime import datetime,timedelta
def dt_parse(t):
    ret = datetime.strptime(t[0:16],'%Y-%m-%dT%H:%M')
    if t[17]=='+':
       ret-=timedelta(hours=int(t[18:20]),minutes=int(t[20:]))
    Elif t[17]=='-':
       ret+=timedelta(hours=int(t[18:20]),minutes=int(t[20:]))
    return ret

print(dt_parse('2017-01-12T14:12 -0530'))
13
Uri Goren

La réponse d'Uri est grande, m'a sauvé la vie, mais quand tu as USE_TZ = True vous devez faire attention à l'heure, pour éviter l'avertissement "RuntimeWarning: DateTimeField" est préférable si vous ajoutez l'utc au retour.

import pytz
from datetime import datetime, timedelta
def dt_parse(t):
    ret = datetime.strptime(t[0:19],'%Y-%m-%dT%H:%M:%S')
    if t[23]=='+':
        ret-=timedelta(hours=int(t[24:26]), minutes=int(t[27:]))
    Elif t[23]=='-':
        ret+=timedelta(hours=int(t[24:26]), minutes=int(t[27:]))
    return ret.replace(tzinfo=pytz.UTC)
0
LaBE