web-dev-qa-db-fra.com

Comment vérifier si un objet datetime est localisé avec pytz?

Je souhaite stocker un objet datetime avec un fuseau horaire UTC localisé. La méthode qui stocke l'objet datetime peut recevoir un objet datetime non localisé (naïf) ou un objet qui a déjà été localisé. Comment déterminer si une localisation est nécessaire?

Code manquant si condition:

class MyClass:
  def set_date(self, d):
    # what do i check here?
    # if(d.tzinfo):
      self.date = d.astimezone(pytz.utc)
    # else:
      self.date = pytz.utc.localize(d)
53
chiborg

Comment déterminer si une localisation est nécessaire?

De datetime docs :

  • un objet datetime d est au courant si:

    d.tzinfo is not None and d.tzinfo.utcoffset(d) is not None
    
  • d est naïf si:

    d.tzinfo is None or d.tzinfo.utcoffset(d) is None
    

Bien que si d soit un objet datetime représentant l'heure dans le fuseau horaire UTC, vous pouvez utiliser dans les deux cas:

self.date = d.replace(tzinfo=pytz.utc)

Cela fonctionne indépendamment du fait que d est sensible au fuseau horaire ou naïf.

Remarque: n'utilisez pas la méthode datetime.replace() avec un fuseau horaire avec un décalage utc non fixe (il est correct de l'utiliser avec le fuseau horaire UTC mais sinon vous devez utiliser tz.localize() méthode).

80
jfs

si vous voulez vérifier si un objet datetime 'd' est localisé, vérifiez le d.tzinfo, s'il est Aucun, pas de localisation.

23
Cédric Julien

Voici une fonction résumant la première réponse.

def tz_aware(dt):
    return dt.tzinfo is not None and dt.tzinfo.utcoffset(dt) is not None
2
Derek R.

Voici une fonction plus complète pour convertir ou contraindre un obj d'horodatage en utc. S'il atteint l'exception, cela signifie que l'horodatage n'est pas localisé. Comme il est recommandé de toujours travailler en UTC dans le code, cette fonction est très utile au niveau d'entrée de la persistance.

def convert_or_coerce_timestamp_to_utc(timeobj):
        out = timeobj
        try:
            out = timeobj.astimezone(pytz.utc) # aware object can be in any timezone
        except (ValueError,TypeError) as exc: # naive
            out = timeobj.replace(tzinfo=pytz.utc)
        return out

Le petit ajout du `` try catch '' dans la réponse de J.F. Sebastian est la condition de capture supplémentaire, sans laquelle tous les cas naïfs ne seront pas capturés par la fonction.

2
eiTan LaVi