attribute 'tzinfo' of 'datetime.datetime' objects is not writable
如何设置刚刚从数据存储中发出的日期时间实例的时区?
当它第一次出现时它是UTC。 我想把它改成EST。
我正在尝试,例如:
1 2 | class Book( db.Model ): creationTime = db.DateTimeProperty() |
检索Book时,我想立即设置其tzinfo:
1 | book.creationTime.tzinfo = EST |
我将这个例子用于我的EST对象
但是我得到:
1 | attribute 'tzinfo' of 'datetime.datetime' objects is not writable |
我已经看到了一些推荐pytz和python-dateutil的答案,但我真的想要回答这个问题。
即,在你的情况下,而不是
1 | book.creationTime.tzinfo = EST |
你必须编码
1 | book.creationTime = book.creationTime.replace(tzinfo=EST) |
如果您正在接收EST中的日期时间,但未设置其tzinfo字段,请使用
如果您正在接收UDT中的日期时间,并且您希望它在EST中,那么您需要astimezone。http://docs.python.org/library/datetime.html#datetime.datetime.astimezone
在绝大多数情况下,您的数据库应该在UDT中存储和返回数据,您不需要使用replace(除了可能分配UDT tzinfo)。
你想要的就是文档中的内容。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | 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 |
输出:
1 2 3 | 2010-01-18 17:08:02.741482 None 2010-01-18 17:08:02.741482-05:00 |