¿Cómo verificar si un objeto de fecha y hora está localizado con pytz?

Quiero almacenar un objeto de fecha y hora con una zona horaria UTC localizada. Al método que almacena el objeto datetime se le puede dar un objeto datetime (naive) no localizado o un objeto que ya se ha localizado. ¿Cómo puedo determinar si la localización es necesaria?

Código con falta si la condición:

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) 

¿Cómo puedo determinar si la localización es necesaria?

De documentos de datetime :

  • un objeto datetime d es consciente si:

     d.tzinfo is not None and d.tzinfo.utcoffset(d) is not None 
  • d es ingenuo si

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

Aunque si d es un objeto de fecha y hora que representa el tiempo en la zona horaria UTC, entonces podría usar en ambos casos:

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

Funciona independientemente de si la zona horaria es consciente o ingenua.

Nota: no use el método datetime.replace() con una zona horaria con un desplazamiento utc no fijo (está bien usarlo con la zona horaria UTC, pero de lo contrario debería usar el método tz.localize() ).

Si desea verificar si un objeto de fecha y hora ‘d’ está localizado, verifique d.tzinfo, si es Ninguno, no hay localización.

Aquí hay una función más completa para convertir o forzar una marca de tiempo obj a utc. Si llega a la excepción, esto significa que la marca de tiempo no está localizada. Ya que es una buena práctica trabajar siempre en UTC dentro del código, esta función es muy útil en el nivel de entrada desde la persistencia.

 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 

La pequeña adición del ‘try catch’ en la respuesta de JF Sebastian es la condición de catch adicional, sin la cual no todos los casos ingenuos serán capturados por la función.

Aquí está una función que envuelve la respuesta superior.

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