我有一条 python datetime
使用 datetime.utcnow()
创建的实例并保存在数据库中。
为了显示,我想转换 datetime
从数据库中检索到本地的实例datetime
使用默认的本地时区(即,好像 datetime
是使用 datetime.now()
创建的)。
如何转换 UTC datetime
到本地 datetime
仅使用 python 标准库(例如,没有 pytz
依赖项)?
似乎一种解决方案是使用 datetime.astimezone(tz)
,但是如何获得默认的本地时区?
最佳答案
在 Python 3.3+ 中:
from datetime import datetime, timezone
def utc_to_local(utc_dt):
return utc_dt.replace(tzinfo=timezone.utc).astimezone(tz=None)
在 Python 2/3 中:
import calendar
from datetime import datetime, timedelta
def 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 pytz
local_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+0400
2010-12-06 20:29:07.730000 MSK+0300
2012-11-08 14:19:50.093745 MSK+0400
python 2
2010-06-06 21:29:07.730000
2010-12-06 20:29:07.730000
2012-11-08 14:19:50.093911
皮茨
2010-06-06 21:29:07.730000 MSD+0400
2010-12-06 20:29:07.730000 MSK+0300
2012-11-08 14:19:50.146917 MSK+0400
注意:它考虑了 DST 和 MSK 时区最近更改的 UTC 偏移量。
我不知道非 pytz 解决方案是否适用于 Windows。
关于python - 如何仅使用标准库将 UTC 日期时间转换为本地日期时间?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4563272/