атрибут 'tzinfo' объектов 'datetime.datetime' не доступен для записи

Как установить часовой пояс экземпляра datetime, который только что вышел из хранилища данных?

Когда он впервые появляется, он находится в UTC. Я хочу изменить его на EST.

Я пытаюсь, например:

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

Когда книга извлекается, я хочу установить ее tzinfo немедленно:

 book.creationTime.tzinfo = EST 

Где я использую этот пример для моего объекта EST

Однако я получаю:

 атрибут 'tzinfo' объектов 'datetime.datetime' не доступен для записи

Я видел несколько ответов, которые рекомендуют pytz и python-dateutil, но я действительно хочу ответить на этот вопрос.

  • Печать правильного времени с использованием часовых поясов, Python
  • Python timezone '% z' директива для datetime.strptime () недоступна
  • Извлечение исторических секунд прыжка из tzdata
  • 3 Solutions collect form web for “атрибут 'tzinfo' объектов 'datetime.datetime' не доступен для записи”

    Объекты datetime неизменны, поэтому вы никогда не изменяете ни один из их атрибутов – вы создаете новый объект с некоторыми атрибутами один и тот же, а некоторые разные, и назначаете его тем, что вам нужно, чтобы назначить его.

    Т.е. в вашем случае вместо

     book.creationTime.tzinfo = EST 

    вам нужно закодировать

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

    Если вы получаете дату и время, dt.replace(tzinfo=tz) в EST, но не заданное поле tzinfo, используйте dt.replace(tzinfo=tz) чтобы назначить tzinfo без изменения времени. (Ваша база данных должна делать это за вас.)

    Если вы получаете дату и время, которое находится в UDT, и вы хотите его в EST, вам нужна асинметровая зона. http://docs.python.org/library/datetime.html#datetime.datetime.astimezone

    В подавляющем большинстве случаев ваша база данных должна хранить и возвращать данные в UDT, и вам не нужно использовать замену (за исключением, возможно, назначения UDT tzinfo).

    То, что вы хотите, находится прямо в документах .

     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 
    Python - лучший язык программирования в мире.