如何设置刚刚从数据存储区中出来的日期时间实例的时区?
首次发布时,它是UTC。我想把它改成EST。
我正在尝试,例如:
class Book( db.Model ):
creationTime = db.DateTimeProperty()
检索Book时,我想立即设置其tzinfo:
book.creationTime.tzinfo = EST
我的EST对象I use this example的位置
但是我得到了:
attribute 'tzinfo' of 'datetime.datetime' objects is not writable
我已经看过一些推荐pytz和python-dateutil的答案,但我真的想要回答这个问题。
答案 0 :(得分:47)
datetime
的对象是不可变的,所以你永远不会改变它们的任何属性 - 你创建一个 new 对象,其中一些属性相同,有些不同,并将它分配给无论你需要什么来分配它。
即,在您的情况下,而不是
book.creationTime.tzinfo = EST
你必须编码
book.creationTime = book.creationTime.replace(tzinfo=EST)
答案 1 :(得分:6)
如果您在 EST中收到的日期时间,但未设置其tzinfo字段,请使用dt.replace(tzinfo=tz)
分配tzinfo而不修改时间。 (您的数据库应该为您执行此操作。)
如果您收到UDT中的日期时间,并且您希望它在EST中,那么您需要astimezone。 http://docs.python.org/library/datetime.html#datetime.datetime.astimezone
在绝大多数情况下,您的数据库应该在UDT中存储和返回数据,您不需要使用replace(除了可能分配UDT tzinfo)。
答案 2 :(得分:0)
你想要的是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
输出:
2010-01-18 17:08:02.741482
None
2010-01-18 17:08:02.741482-05:00