We can use time.tzname
get a local timezone name, but that name is not compatible with pytz.timezone
.
In fact, the name returned by time.tzname
is ambiguous. This method returns ('CST', 'CST')
in my system, but 'CST' can indicate four timezones:
The pytz package encourages using UTC for internal timezone representation by including a special UTC implementation based on the standard Python reference implementation in the Python documentation. The UTC timezone unpickles to be the same instance, and pickles to a smaller size than other pytz tzinfo instances.
The current client's system time zone can be read using function module GET_SYSTEM_TIMEZONE. Determines the date and time in the system time zone from a time stamp. GET TIME STAMP FIELD DATA(ts). INTO @DATA(tzone).
pytz will help you to tell if an date is under DST influence by checking dst() method.
tzlocal
module returns pytz tzinfo's object corresponding to the local timezone:
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
It works even during daylight savings time transitions when local time may be ambiguous.
local_tz
also works for past dates even if utc offset for the local timezone was different at the time. dateutil.tz.tzlocal()
-based solution fails in this case e.g., in Europe/Moscow timezone (example from 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 returns wrong UTC+4 offset instead of the correct UTC+3 on 1970-01-01.
For those bumping into this in 2017 dateutil.tz.tzlocal()
is still broken. The above example works now because the current utf offset is UTC+3 in Moscow (that by accident is equal to the utc offset from 1970). To demonstrate the error we can choose a date when utc offset is 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 returns wrong UTC+3 offset instead of the correct UTC+4 on 2014-06-01.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With