tzlocal
モジュールは、ローカル タイムゾーンに対応する pytz tzinfo のオブジェクトを返します。
import time
from datetime import datetime
import pytz # $ pip install pytz
from tzlocal import get_localzone # $ pip install tzlocal
# get local timezone
local_tz = get_localzone()
# test it
# utc_now, now = datetime.utcnow(), datetime.now()
ts = time.time()
utc_now, now = datetime.utcfromtimestamp(ts), datetime.fromtimestamp(ts)
local_now = utc_now.replace(tzinfo=pytz.utc).astimezone(local_tz) # utc -> local
assert local_now.replace(tzinfo=None) == now
地方時があいまいな場合がある夏時間の移行中にも機能します。
local_tz
ローカル タイムゾーンの utc オフセットがその時点で異なっていたとしても、過去の日付に対しても機能します。dateutil.tz.tzlocal()
この場合、ベースのソリューションは失敗します。たとえば、ヨーロッパ/モスクワのタイムゾーン (2013 年の例) では失敗します。
>>> import os, time
>>> os.environ['TZ'] = 'Europe/Moscow'
>>> time.tzset()
>>> from datetime import datetime
>>> from dateutil.tz import tzlocal
>>> from tzlocal import get_localzone
>>> dateutil_tz = tzlocal()
>>> tzlocal_tz = get_localzone()
>>> datetime.fromtimestamp(0, dateutil_tz)
datetime.datetime(1970, 1, 1, 4, 0, tzinfo=tzlocal())
>>> datetime.fromtimestamp(0, tzlocal_tz)
datetime.datetime(1970, 1, 1, 3, 0, tzinfo=<DstTzInfo 'Europe/Moscow' MSK+3:00:00 STD>)
dateutil は、1970-01-01 の正しい UTC+3 ではなく、間違ったUTC+4 オフセットを返します。
2017年にこれにぶつかった人にとって dateutil.tz.tzlocal()
は、まだ壊れています。上記の例は、現在の utf オフセットがモスクワの UTC+3 であるため (偶然にも 1970 年の utc オフセットに等しい) 動作します。エラーを示すために、utc オフセットが UTC+4 の日付を選択できます。
>>> import os, time
>>> os.environ['TZ'] = 'Europe/Moscow'
>>> time.tzset()
>>> from datetime import datetime
>>> from dateutil.tz import tzlocal
>>> from tzlocal import get_localzone
>>> dateutil_tz = tzlocal()
>>> tzlocal_tz = get_localzone()
>>> ts = datetime(2014, 6,1).timestamp() # get date in 2014 when gmtoff=14400 in Moscow
>>> datetime.fromtimestamp(ts, dateutil_tz)
datetime.datetime(2014, 5, 31, 23, 0, tzinfo=tzlocal())
>>> datetime.fromtimestamp(ts, tzlocal_tz)
datetime.datetime(2014, 6, 1, 0, 0, tzinfo=<DstTzInfo 'Europe/Moscow' MSK+4:00:00 STD>)
dateutil は、2014-06-01 の正しい UTC+4 ではなく、間違ったUTC+3 オフセットを返します。