I want to get the default timezone (PST) of my system from Python. What's the best way to do that? I'd like to avoid forking another process.
-
related: [get local time zone name on Windows](https://stackoverflow.com/q/62330675/10197418) – FObersteiner Dec 05 '21 at 10:40
10 Answers
This should work:
import time
time.tzname
time.tzname
returns a tuple of two strings: The first is the name of the local non-DST timezone, the second is the name of the local DST timezone.
Example return: ('MST', 'MDT')

- 1,151
- 1
- 17
- 25

- 52,533
- 16
- 102
- 136
-
47To take this one further, you can use `time.tzname[time.daylight]` to get the name of the current timezone, accounting for daylight saving time. – Dan Breen Aug 31 '12 at 14:51
-
37Again, 'time.daylight' does not indicate that DST is active. It merely indicates whether or not DST is observed by the timezone. You're looking for 'time.localtime().tm_isdst'. – marr75 Nov 21 '13 at 16:11
-
1Just to add for Windows users, the values for timezone was defined in `HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones\` – swdev Apr 04 '14 at 14:34
-
5[`time.tzname` may return a wrong value](http://bugs.python.org/issue22798) if the local timezone had different abbreviations in the past (Python uses values from January, July or the current (import/`tzset()` time) value). `tzlocal` module could be used to get the correct tzname for a given date. – jfs Jan 13 '15 at 09:56
-
5
-
1@senaps : Yes, `d=datetime.datetime.now(tz=pytz.timezone("US/Pacific"))` and `print(d.tzinfo.zone)`. It only works if the timezone was assigned in the original datetime object and not deduced. – ingyhere May 22 '20 at 17:46
Gives a UTC offset like in ThomasH's answer, but takes daylight savings into account.
>>> import time
>>> offset = time.timezone if (time.localtime().tm_isdst == 0) else time.altzone
>>> offset / 60 / 60 * -1
-9
The value of time.timezone
or time.altzone
is in seconds West of UTC (with areas East of UTC getting a negative value). This is the opposite to how we'd actually like it, hence the * -1.
time.localtime().tm_isdst
will be zero if daylight savings is currently not in effect (although this may not be correct if an area has recently changed their daylight savings law).
EDIT: marr75 is correct, I've edited the answer accordingly.

- 107,652
- 25
- 181
- 264

- 8,632
- 6
- 45
- 61
-
3To be safe, I think the offset check should be reversed (altzone if dst = 1 else timezone). If DST status is somehow unknown, `tm_isdst` will be `-1`, and the current code would default to `altzone` in this case. For regions that don't use DST, this value is never correct, so `timezone` should probably be the fallback. (I'm not sure if `-1` is actually possible output from `localtime` though) – nmclean Sep 11 '14 at 13:14
-
2[all altzone, timezone-based solution may fail in some edge cases](http://bugs.python.org/issue1647654) – jfs Jan 13 '15 at 09:51
I found this to work well:
import datetime
tz_string = datetime.datetime.now(datetime.timezone.utc).astimezone().tzname()
For me this was able to differentiate between daylight savings and not.
From Python 3.6 you can do:
tz_string = datetime.datetime.now().astimezone().tzname()
Or
tz_string = datetime.datetime.now().astimezone().tzinfo
Reference with more detail: https://stackoverflow.com/a/39079819/4549682

- 57,944
- 17
- 167
- 143

- 13,746
- 5
- 87
- 117
-
1as from python 3.6 you can just write `tz_string = datetime.datetime.now().astimezone().tzname()` Also if you want to get more than just the timezone's name you can use: `datetime.now().astimezone().tzinfo` – gelonida Aug 27 '22 at 21:18
Check out the Python Time Module.
from time import gmtime, strftime
print(strftime("%z", gmtime()))
Pacific Standard Time

- 124,992
- 159
- 614
- 958

- 3,306
- 24
- 23
-
-
-
@ SilentGhost: Ah, my apologies, missed that. Just ran a new test and both %z and %Z both work in Python 2.6. – ahawker Jul 10 '09 at 18:38
-
11
-
4>>> from time import gmtime, strftime >>> print strftime('%z', gmtime()) Pacific Standard Time >>> print strftime('%Z', gmtime()) Pacific Standard Time I disagree. – ahawker Jul 10 '09 at 23:23
-
http://docs.python.org/library/time.html#time.strftime Also mentions nothing about case on the %Z format. – ahawker Jul 10 '09 at 23:33
-
1well, 1. on my machine they produce different outputs; 2. docs don't say anything about lower-case z, because only upper-case Z is a valid literal and lower case is not supposed to be used. http://docs.python.org/library/datetime.html#strftime-behavior here are some details of what lower-case z produced (even in time module). – SilentGhost Jul 11 '09 at 09:25
-
furthermore, docs state (http://docs.python.org/library/time.html#id2) that use of %Z is deprecated. – SilentGhost Jul 11 '09 at 09:29
-
3Also check out [dateutil](https://pypi.python.org/pypi/python-dateutil) and [tzlocal](https://pypi.python.org/pypi/tzlocal) that helps with this. %z (and %Z) produce non-standard, ambiguous platform dependent strings that aren't very useful. – Lennart Regebro Aug 02 '13 at 13:16
-
6In Python 2.7 on Linux, `%Z` produces TZ acronym eg. `CET`, while `%z` produces offset, eg. `+0100` – vartec Nov 07 '13 at 15:48
-
1This gave me GMT, which is not the system timezone on my machine. The `import time; time.tzname` solution gave me (EST, EDT) which is correct for my purposes. – Stew Oct 04 '16 at 19:27
-
2This gave me the wrong timezone (again, GMT) in Python 2, but the correct one in Python 3. – zondo Nov 12 '16 at 03:52
-
https://lh3.googleusercontent.com/MBvbL9sVUhLyA2KN9Wa67yoBISbDy8cnSVyq7HatgmKnLOPEqyTr6Qd427Rxulz6rpcN0uB4r9OYqzdYiGEfyJ3cUgMBbjagA-MQ_65loDDG8aRiefyGltLx2V51yDRFLYSEP5IN – wordsforthewise Jul 12 '18 at 02:57
-
2This is incorrect, GMT gives gmt time, you're supposed to use `localtime` – Mojimi Jul 14 '20 at 17:27
For Python 3.6+ this can be easily achieved by following code:
import datetime
local_timezone = datetime.datetime.utcnow().astimezone().tzinfo
print(local_timezone)
But with Python < 3.6 calling astimezone()
on naive datetime doesn't work. So we've to do it in a slightly different way.
So for Python 3.x,
import datetime
local_timezone = datetime.datetime.now(datetime.timezone.utc).astimezone().tzinfo
print(local_timezone)
Sample Output:
On Netherlands Server(Python 3.6.9):
CEST
On Bangladesh Server(Python 3.8.2):
+06
More details can be found on this thread.

- 3,732
- 30
- 37
The code snippets for calculating offset are incorrect, see http://bugs.python.org/issue7229.
The correct way to handle this is:
def local_time_offset(t=None):
"""Return offset of local zone from GMT, either at present or at time t."""
# python2.3 localtime() can't take None
if t is None:
t = time.time()
if time.localtime(t).tm_isdst and time.daylight:
return -time.altzone
else:
return -time.timezone
This is in all likelihood, not the exact question that the OP asked, but there are two incorrect snippets on the page and time bugs suck to track down and fix.

- 5,666
- 1
- 27
- 41
-
1. if you know `tm_isdst`; you don't need to check `daylight` 2. [all `altzone`, `timezone`-based solution may fail in some edge cases](http://bugs.python.org/issue1647654) – jfs Jan 13 '15 at 09:49
-
This works for me on both python 2.6 and 3.6. Also important to note that the offset is in *seconds*. – Seth Johnson Mar 17 '20 at 10:44
To obtain timezone information in the form of a datetime.tzinfo
object, use dateutil.tz.tzlocal()
:
from dateutil import tz
myTimeZone = tz.tzlocal()
This object can be used in the tz
parameter of datetime.datetime.now()
:
from datetime import datetime
from dateutil import tz
localisedDatetime = datetime.now(tz = tz.tzlocal())
or the tz
parameter of datetime
object via datetime.datetime.astimezone()
:
from datetime import datetime
from dateutil import tz
unlocalisedDatetime = datetime.now()
localisedDatetime = unlocalisedDatetime.astimezone(tz = tz.tzlocal())

- 8,655
- 5
- 60
- 87
import tzlocal
tz_info = tzlocal.get_localzone() # 'US/Central' or 'Asia/Calcutta'
dt = datetime.now() # 2023-01-15 15:17:24.412430
print(tz_info.localize(dt) # 2023-01-15 15:17:24.412430-06:00
with tzlocal
we will be able to get the local timezone.

- 51
- 3
Getting offset from UTC as timedelta
:
from datetime import datetime, timezone
now = datetime.now()
now.replace(tzinfo=timezone.utc) - now.astimezone(timezone.utc)
Or like this (more obscure but also works):
datetime.now(timezone.utc).astimezone().tzinfo.utcoffset(None)
Both solutions give the same result. For example: datetime.timedelta(seconds=7200)

- 341
- 2
- 10
The problem is there are multiple time zone formats, namely:
- IANA Time Zone Database: "TZ Identifier" (e.g.
"Africa/Addis_Ababa"
) - IANA Time Zone Database: "abbreviation" (e.g.
"EAT"
) - Microsoft Time Zone Index (e.g.
"E. Africa Standard Time"
) - UTC offset (e.g.
"+03:00"
or"UTC+03:00"
) - The ISO 3166-1 country codes are sometimes also used to reference time zones but these do not map cleanly (e.g.
"ET"
,"ETH"
, or231
)
Here's how to get all time zones and the system time zone, in all these formats:
Database Name | Example | List all time zones | Get system time zone |
---|---|---|---|
IANA Time Zone Identifiers | 'Asia/Bangkok' |
import zoneinfo as zi; zi.available_timezones() or pytz.all_timezones |
import tzlocal as tzl; str(tzl.get_localzone()) |
IANA Time Zone Abbreviations | 'ICT' |
In Python I'm not sure how; see the IANA wiki page for a list | See this answer |
Microsoft Time Zone Index | 'SE Asia Standard Time' |
** Note 1 | time.tzname[0] |
Time zone offset | '+07:00' |
N/A | ** Note 2 |
** Note 1: in Powershell,
[System.TimeZoneInfo]::GetSystemTimeZones()
** Note 2: in Python,
iana_tz = str(tzlocal.get_localzone())
pytz_tz = pytz.timezone(iana_tz)
offset_str = datetime.datetime.now().astimezone(pytz_tz).strftime("%z")
offset_str = offset_str[:3] + ':' + offset_str[3:]

- 13,721
- 9
- 42
- 58