with tutorial framework espaƱol djangoproject desde con cero applications python google-app-engine datetime tzinfo

python - tutorial - atributo ''tzinfo'' de los objetos ''datetime.datetime'' no se puede escribir



tutorial django (3)

¿Cómo configuro la zona horaria de una instancia de fecha y hora que acaba de salir del almacén de datos?

Cuando sale por primera vez, está en UTC. Quiero cambiarlo a EST.

Lo intento, por ejemplo:

class Book( db.Model ): creationTime = db.DateTimeProperty()

Cuando se recupera un libro, quiero configurar su tzinfo inmediatamente:

book.creationTime.tzinfo = EST

Donde uso este ejemplo para mi objeto EST

Sin embargo, obtengo:

attribute ''tzinfo'' of ''datetime.datetime'' objects is not writable

He visto una serie de respuestas que recomiendan pytz y python-dateutil, pero realmente quiero una respuesta a esta pregunta.


Lo que quieres está ahí en los docs .

from datetime import tzinfo, timedelta, datetime ZERO = timedelta(0) HOUR = timedelta(hours=1) DSTSTART = datetime(1, 4, 1, 2) DSTEND = datetime(1, 10, 25, 1) def first_sunday_on_or_after(dt): days_to_go = 6 - dt.weekday() if days_to_go: dt += timedelta(days_to_go) return dt class USTimeZone(tzinfo): def __init__(self, hours, reprname, stdname, dstname): self.stdoffset = timedelta(hours=hours) self.reprname = reprname self.stdname = stdname self.dstname = dstname def __repr__(self): return self.reprname def tzname(self, dt): if self.dst(dt): return self.dstname else: return self.stdname def utcoffset(self, dt): return self.stdoffset + self.dst(dt) def dst(self, dt): if dt is None or dt.tzinfo is None: # An exception may be sensible here, in one or both cases. # It depends on how you want to treat them. The default # fromutc() implementation (called by the default astimezone() # implementation) passes a datetime with dt.tzinfo is self. return ZERO assert dt.tzinfo is self # Find first Sunday in April & the last in October. start = first_sunday_on_or_after(DSTSTART.replace(year=dt.year)) end = first_sunday_on_or_after(DSTEND.replace(year=dt.year)) # Can''t compare naive to aware objects, so strip the timezone from # dt first. if start <= dt.replace(tzinfo=None) < end: return HOUR else: return ZERO now = datetime.now() print now print now.tzinfo Eastern = USTimeZone(-5, ''Eastern'', ''EST'', ''EDT'') now_tz_aware = now.replace(tzinfo=Eastern) print now_tz_aware

salida:

2010-01-18 17:08:02.741482 None 2010-01-18 17:08:02.741482-05:00


Los objetos de datetime son inmutables, por lo que nunca cambiará ninguno de sus atributos: crea un objeto nuevo con algunos atributos iguales, y otros diferentes, y lo asigna a lo que necesite asignar.

Es decir, en su caso, en lugar de

book.creationTime.tzinfo = EST

tienes que codificar

book.creationTime = book.creationTime.replace(tzinfo=EST)


Si recibe una fecha y hora en EST, pero no tiene configurado su campo tzinfo, use dt.replace(tzinfo=tz) para asignar un tzinfo sin modificar la hora. (Su base de datos debería estar haciendo esto por usted).

Si está recibiendo una fecha y hora que está en UDT y la quiere en EST, entonces necesita astimezone. http://docs.python.org/library/datetime.html#datetime.datetime.astimezone

En la gran mayoría de los casos, su base de datos debe almacenar y devolver datos en UDT, y no debería necesitar reemplazar (excepto posiblemente asignar un UDT tzinfo).