慕莱坞森
在Python 3.3+中:from datetime import datetime, timezonedef utc_to_local(utc_dt): return utc_dt.replace(tzinfo=timezone.utc).astimezone(tz=None)在Python 2/3中:import calendarfrom datetime import datetime, timedeltadef utc_to_local(utc_dt): # get integer timestamp to avoid precision lost timestamp = calendar.timegm(utc_dt.timetuple()) local_dt = datetime.fromtimestamp(timestamp) assert utc_dt.resolution >= timedelta(microseconds=1) return local_dt.replace(microsecond=utc_dt.microsecond)使用pytz(Python 2/3):import pytzlocal_tz = pytz.timezone('Europe/Moscow') # use your local timezone name here# NOTE: pytz.reference.LocalTimezone() would produce wrong result here## You could use `tzlocal` module to get local timezone on Unix and Win32# from tzlocal import get_localzone # $ pip install tzlocal# # get local timezone # local_tz = get_localzone()def utc_to_local(utc_dt): local_dt = utc_dt.replace(tzinfo=pytz.utc).astimezone(local_tz) return local_tz.normalize(local_dt) # .normalize might be unnecessary例def aslocaltimestr(utc_dt): return utc_to_local(utc_dt).strftime('%Y-%m-%d %H:%M:%S.%f %Z%z')print(aslocaltimestr(datetime(2010, 6, 6, 17, 29, 7, 730000)))print(aslocaltimestr(datetime(2010, 12, 6, 17, 29, 7, 730000)))print(aslocaltimestr(datetime.utcnow()))产量Python 3.32010-06-06 21:29:07.730000 MSD+04002010-12-06 20:29:07.730000 MSK+03002012-11-08 14:19:50.093745 MSK+0400Python 22010-06-06 21:29:07.730000 2010-12-06 20:29:07.730000 2012-11-08 14:19:50.093911 pytz2010-06-06 21:29:07.730000 MSD+04002010-12-06 20:29:07.730000 MSK+03002012-11-08 14:19:50.146917 MSK+0400注意:它考虑了DST和最近MSK时区的utc偏移的变化。我不知道非pytz解决方案是否适用于Windows。
慕慕森
我想我想出来了:计算自纪元以来的秒数,然后使用time.localtime转换为本地timzeone,然后将时间结构转换回日期时间......EPOCH_DATETIME = datetime.datetime(1970,1,1)SECONDS_PER_DAY = 24*60*60def utc_to_local_datetime( utc_datetime ): delta = utc_datetime - EPOCH_DATETIME utc_epoch = SECONDS_PER_DAY * delta.days + delta.seconds time_struct = time.localtime( utc_epoch ) dt_args = time_struct[:6] + (delta.microseconds,) return datetime.datetime( *dt_args )它正确应用夏季/冬季夏令时:>>> utc_to_local_datetime( datetime.datetime(2010, 6, 6, 17, 29, 7, 730000) )datetime.datetime(2010, 6, 6, 19, 29, 7, 730000)>>> utc_to_local_datetime( datetime.datetime(2010, 12, 6, 17, 29, 7, 730000) )datetime.datetime(2010, 12, 6, 18, 29, 7, 730000)