35

データストアから出てきたばかりの datetime インスタンスのタイムゾーンを設定するにはどうすればよいですか?

最初に出てくるときはUTCです。ESTに変更したいです。

たとえば、次のようにしています。

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

Book が取得されたら、その tzinfo をすぐに設定したいと思います。

book.creationTime.tzinfo = EST

この例を EST オブジェクトに使用する場所

しかし、私は得る:

「datetime.datetime」オブジェクトの属性「tzinfo」は書き込み可能ではありません

pytz と python-dateutil を推奨する多くの回答を見てきましたが、この質問に対する回答が本当に必要です。

4

3 に答える 3

61

datetimeのオブジェクトは不変であるため、それらの属性を変更することはありません。同じ属性と異なる属性を持つ新しいオブジェクトを作成し、それを割り当てる必要があるものに割り当てます。

つまり、あなたの場合、代わりに

book.creationTime.tzinfo = EST

あなたはコーディングする必要があります

book.creationTime = book.creationTime.replace(tzinfo=EST)
于 2010-01-18T21:52:01.157 に答える
7

EST内の日時を受信して​​いるが、その tzinfo フィールドが設定されていない場合はdt.replace(tzinfo=tz)、時刻を変更せずに tzinfo を割り当てるために使用します。(データベースがこれを行う必要があります。)

UDT の datetime を受け取っていて、それを EST で取得したい場合は、astimezone が必要です。 http://docs.python.org/library/datetime.html#datetime.datetime.astimezone

ほとんどの場合、データベースはデータを UDT に格納して返す必要があり、replace を使用する必要はありません (おそらく UDT tzinfo を割り当てる場合を除きます)。

于 2010-01-18T21:50:33.840 に答える
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
于 2010-01-18T21:49:19.587 に答える