Python: Figure out local timezone
Solution 1
Try dateutil, which has a tzlocal type that does what you need.
Solution 2
In Python 3.x, local timezone can be figured out like this:
import datetime
LOCAL_TIMEZONE = datetime.datetime.now(datetime.timezone.utc).astimezone().tzinfo
It's a tricky use of datetime
's code .
For python < 3.6, you'll need
import datetime
LOCAL_TIMEZONE = datetime.datetime.now(datetime.timezone(datetime.timedelta(0))).astimezone().tzinfo
Solution 3
to compare UTC timestamps from a log file with local timestamps.
It is hard to find out Olson TZ name for a local timezone in a portable manner. Fortunately, you don't need it to perform the comparison.
tzlocal
module returns a pytz timezone corresponding to the local timezone:
from datetime import datetime
import pytz # $ pip install pytz
from tzlocal import get_localzone # $ pip install tzlocal
tz = get_localzone()
local_dt = tz.localize(datetime(2010, 4, 27, 12, 0, 0, 0), is_dst=None)
utc_dt = local_dt.astimezone(pytz.utc) #NOTE: utc.normalize() is unnecessary here
Unlike other solutions presented so far the above code avoids the following issues:
- local time can be ambiguous i.e., a precise comparison might be impossible for some local times
- utc offset can be different for the same local timezone name for dates in the past. Some libraries that support timezone-aware datetime objects (e.g.,
dateutil
) fail to take that into account
Note: to get timezone-aware datetime object from a naive datetime object, you should use*:
local_dt = tz.localize(datetime(2010, 4, 27, 12, 0, 0, 0), is_dst=None)
instead of:
#XXX fails for some timezones
local_dt = datetime(2010, 4, 27, 12, 0, 0, 0, tzinfo=tz)
*is_dst=None
forces an exception if given local time is ambiguous or non-existent.
If you are certain that all local timestamps use the same (current) utc offset for the local timezone then you could perform the comparison using only stdlib:
# convert a naive datetime object that represents time in local timezone to epoch time
timestamp1 = (datetime(2010, 4, 27, 12, 0, 0, 0) - datetime.fromtimestamp(0)).total_seconds()
# convert a naive datetime object that represents time in UTC to epoch time
timestamp2 = (datetime(2010, 4, 27, 9, 0) - datetime.utcfromtimestamp(0)).total_seconds()
timestamp1
and timestamp2
can be compared directly.
Note:
-
timestamp1
formula works only if the UTC offset at epoch (datetime.fromtimestamp(0)
) is the same as now -
fromtimestamp()
creates a naive datetime object in the current local timezone -
utcfromtimestamp()
creates a naive datetime object in UTC.
Solution 4
I was asking the same to myself, and I found the answer in 1:
Take a look at section 8.1.7: the format "%z" (lowercase, the Z uppercase returns also the time zone, but not in the 4-digit format, but in the form of timezone abbreviations, like in [3]) of strftime returns the form "+/- 4DIGIT" that is standard in email headers (see section 3.3 of RFC 2822, see [2], which obsoletes the other ways of specifying the timezone for email headers).
So, if you want your timezone in this format, use:
time.strftime("%z")
[1] http://docs.python.org/2/library/datetime.html
[2] https://www.rfc-editor.org/rfc/rfc2822#section-3.3
[3] Timezone abbreviations: http://en.wikipedia.org/wiki/List_of_time_zone_abbreviations , only for reference.
Solution 5
The following appears to work for 3.7+, using standard libs:
from datetime import timedelta
from datetime import timezone
import time
def currenttz():
if time.daylight:
return timezone(timedelta(seconds=-time.altzone),time.tzname[1])
else:
return timezone(timedelta(seconds=-time.timezone),time.tzname[0])
Adam Matan
Team leader, developer, and public speaker. I build end-to-end apps using modern cloud infrastructure, especially serverless tools. My current position is R&D Manager at Corvid by Wix.com, a serverless platform for rapid web app generation. My CV and contact details are available on my Github README.
Updated on September 07, 2021Comments
-
Adam Matan over 2 years
I want to compare UTC timestamps from a log file with local timestamps. When creating the local
datetime
object, I use something like:>>> local_time=datetime.datetime(2010, 4, 27, 12, 0, 0, 0, tzinfo=pytz.timezone('Israel'))
I want to find an automatic tool that would replace the
tzinfo=pytz.timezone('Israel')
with the current local time zone.Any ideas?