pytz UTC转换

52 投票
4 回答
69495 浏览
提问于 2025-04-15 13:59

如何将一个没有时区信息的时间和一个tzinfo转换成UTC时间呢?假设我有:

d = datetime(2009, 8, 31, 22, 30, 30)
tz = timezone('US/Pacific')

第一种方法,受pytz启发:

d_tz = tz.normalize(tz.localize(d))
utc = pytz.timezone('UTC')
d_utc = d_tz.astimezone(utc)

第二种方法,来自UTCDateTimeField

def utc_from_localtime(dt, tz):
    dt = dt.replace(tzinfo=tz)
    _dt = tz.normalize(dt)
    if dt.tzinfo != _dt.tzinfo:
        # Houston, we have a problem...
        # find out which one has a dst offset
        if _dt.tzinfo.dst(_dt):
            _dt -= _dt.tzinfo.dst(_dt)
        else:
            _dt += dt.tzinfo.dst(dt)
    return _dt.astimezone(pytz.utc)

不用说,这两种方法在很多时区下会产生不同的结果。

问题是 - 哪种方法才是正确的呢?

4 个回答

1

使用第一种方法。没有必要重新发明时区转换的轮子。

8

如何将一个没有时区信息的时间和一个时区信息转换成UTC时间?

这个回答列举了一些将本地时间转换为UTC时遇到的问题

from datetime import datetime
import pytz # $ pip install pytz

d = datetime(2009, 8, 31, 22, 30, 30)
tz = pytz.timezone('US/Pacific')

# a) raise exception for non-existent or ambiguous times
aware_d = tz.localize(d, is_dst=None)
## b) assume standard time, adjust non-existent times
#aware_d = tz.normalize(tz.localize(d, is_dst=False))
## c) assume DST is in effect, adjust non-existent times
#aware_d = tz.normalize(tz.localize(naive_d, is_dst=True))

# convert to UTC
utc_d = aware_d.astimezone(pytz.utc)
43

你提到的第一个方法看起来是被认可的,并且应该能够处理夏令时。

你可以稍微简化一下,因为 pytz.utc = pytz.timezone('UTC'),不过你应该已经知道这一点了 :)

tz = timezone('US/Pacific')
def toUTC(d):
    return tz.normalize(tz.localize(d)).astimezone(pytz.utc)

print "Test: ", datetime.datetime.utcnow(), " = ", toUTC(datetime.datetime.now())

撰写回答