仅使用python标准库将python UTC日期时间转换为本地日期时间?

仅使用python标准库将python UTC日期时间转换为本地日期时间?

我有一个使用datetime.utcnow()创建并保存在数据库中的python datetime实例。

为了显示,我想使用默认的本地时区将从数据库检索的日期时间实例转换为本地日期时间(即,就像使用datetime.now()创建日期时间一样)。

如何仅使用python标准库将UTC日期时间转换为本地日期时间(例如,没有pytz依赖项)?

似乎一个解决方案是使用datetime.astimezone(tz),但是如何获得默认的本地时区?


拉风的咖菲猫
浏览 812回答 3
3回答

慕莱坞森

在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。

扬帆大鱼

您不能只使用标准库,因为标准库没有任何时区。你需要pytz或dateutil。>>> from datetime import datetime>>> now = datetime.utcnow()>>> from dateutil import tz>>> HERE = tz.tzlocal()>>> UTC = tz.gettz('UTC')The Conversion:>>> gmt = now.replace(tzinfo=UTC)>>> gmt.astimezone(HERE)datetime.datetime(2010, 12, 30, 15, 51, 22, 114668, tzinfo=tzlocal())或者,你可以通过实现自己的时区来实现没有pytz或dateutil。但这很愚蠢。

慕慕森

我想我想出来了:计算自纪元以来的秒数,然后使用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)
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python