Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get system timezone setting and pass it to pytz.timezone?

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:

  • Central Time Zone (North America) - observed in North America's Central Time Zone
  • China Standard Time
  • Chungyuan Standard Time - the term "Chungyuan Standard Time" is now rarely in use in Taiwan
  • Australian Central Standard Time (ACST)
like image 742
user805627 Avatar asked Nov 04 '12 12:11

user805627


People also ask

What is pytz timezone?

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.

How do I find system time zone?

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).

Does pytz handle DST?

pytz will help you to tell if an date is under DST influence by checking dst() method.


1 Answers

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.

like image 168
jfs Avatar answered Oct 10 '22 20:10

jfs