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

后端 未结 3 591
一生所求
一生所求 2021-02-05 02:01

How do I set the timezone of a datetime instance that just came out of the datastore?

When it first comes out it is in UTC. I want to change it to EST.

I\'m try

相关标签:
3条回答
  • 2021-02-05 02:33

    What you want is right there in the 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
    

    output:

    2010-01-18 17:08:02.741482
    None
    2010-01-18 17:08:02.741482-05:00
    
    0 讨论(0)
  • 2021-02-05 02:46

    datetime's objects are immutable, so you never change any of their attributes -- you make a new object with some attributes the same, and some different, and assign it to whatever you need to assign it to.

    I.e., in your case, instead of

    book.creationTime.tzinfo = EST
    

    you have to code

    book.creationTime = book.creationTime.replace(tzinfo=EST)
    
    0 讨论(0)
  • 2021-02-05 02:54

    If you're receiving a datetime that's in EST, but doesn't have its tzinfo field set, use dt.replace(tzinfo=tz) to assign a tzinfo without modifying the time. (Your database should be doing this for you.)

    If you're receiving a datetime that's in UDT, and you want it in EST, then you need astimezone. http://docs.python.org/library/datetime.html#datetime.datetime.astimezone

    In the vast majority of cases, your database should be storing and returning data in UDT, and you shouldn't need to use replace (except possibly to assign a UDT tzinfo).

    0 讨论(0)
提交回复
热议问题