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