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