With version 3.0 of tzlocal, tzlocal no longer returned
pytz objects, but
zoneinfo objects, which has a different API. Since 4.0, it now restored
partial compatibility for
pytz users through Paul Ganssle's
tzlocal 4.0 also adds an official function
get_localzone_name() to get only
the timezone name, instead of a timezone object. On unix, it can raise an
error if you don't have a timezone name configured, where
will succeed, so only use that if you need the timezone name.
4.0 also adds way more information on what is going wrong in your configuration when the configuration files are unclear or contradictory.
This Python module returns a
tzinfo object (with a pytz_deprecation_shim,
for pytz compatibility) with the local timezone information, under Unix and
It requires Python 3.6 or later, and will use the
package, for Python 3.6 to 3.8.
This module attempts to fix a glaring hole in the
modules, that there is no way to get the local timezone information, unless
you know the zoneinfo name, and under several Linux distros that's hard or
impossible to figure out.
tzlocal you only need to call
get_localzone() and you will get a
tzinfo object with the local time zone info. On some Unices you will
still not get to know what the timezone name is, but you don't need that when
you have the tzinfo file. However, if the timezone name is readily available
it will be used.
These are the systems that are in theory supported:
Windows 2000 and later
Any unix-like system with a
If you have one of the above systems and it does not work, it's a bug. Please report it.
Please note that if you are getting a time zone called
local, this is not
a bug, it's actually the main feature of
tzlocal, that even if your
system does NOT have a configuration file with the zoneinfo name of your time
zone, it will still work.
You can also use
tzlocal to get the name of your local timezone, but only
if your system is configured to make that possible.
tzlocal looks for the
timezone name in
/etc/conf.d/clock. If your
/etc/localtime is a symlink it can also extract the name from that
If you need the name of your local time zone, then please make sure your system is properly configured to allow that.
If your unix system doesn't have a timezone configured, tzlocal will default to UTC.
Load the local timezone:
from tzlocal import get_localzone tz = get_localzone() tz <DstTzInfo 'Europe/Warsaw' WMT+1:24:00 STD>
Create a local datetime:
from datetime import datetime dt = datetime(2015, 4, 10, 7, 22, tzinfo=tz) dt datetime.datetime(2015, 4, 10, 7, 22, tzinfo=<DstTzInfo 'Europe/Warsaw' CEST+2:00:00 DST>)
Lookup another timezone with
backports.zoneinfo on Python 3.8 or earlier):
from zoneinfo import ZoneInfo eastern = ZoneInfo('US/Eastern')
Convert the datetime:
>>> dt.astimezone(eastern) datetime.datetime(2015, 4, 10, 1, 22, tzinfo=<DstTzInfo 'US/Eastern' EDT-1 day, 20:00:00 DST>)
If you just want the name of the local timezone, use
from tzlocal import get_localzone_name get_localzone_name() "Europe/Warsaw"
Please note that under Unix,
get_localzone_name() may fail if there is no zone
get_localzone() would generally succeed.
To create a development environment, create a virtualenv and make a development installation::
$ virtualenv ve $ source ve/bin/activation (Win32: .\ve\Scripts\activate) (ve) $ pip install -e .[test,devenv]
To run tests, just use pytest, coverage is nice as well::
(ve) $ pytest --cov=tzlocal
(Sorry if I forgot someone)
It turns out a lot of Linux distributions make the links between zoneinfo aliases backwards, so instead of linking GB to Europe/London it actually links the other way. When /etc/localtime then links to Europe/London, and you also have a config file saying Europe/London, the code that checks if /etc/localtime is a symlink ends up at GB instead of Europe/London and we get an error, as it thinks GB and Europe/London are different zones.
So now we check the symlink of all timezones in the uniqueness test. We still return the name in the config file, though, so you would only get GB or Zulu returned as the time zone instead of Europe/London or UTC if your only configuration is the /etc/localtime symlink, as that's checked last, and tzlocal will return the first configuration found.
The above change also means that GMT and UTC are no longer seen as synonyms, as zoneinfo does not see them as synonyms. This might be controversial, but you just have to live with it. Pick one and stay with it. ;-)
Returning pytz_deprecation_shim zones to lower the surprise for pytz users.
The Windows OS environment variable 'TZ' will allow an override for setting the timezone. The override timezone will be asserted for timezone validity bit not compared against the systems timezone offset. This allows for overriding the timezone when running tests.
Dropped support for Windows 2000, XP and Vista, supports Windows 7, 8 and 10.
Big refactor; Implemented get_localzone_name() functions.
Adding a Windows OS environment variable 'TZ' will allow an override for setting the timezone (also see 4.0b3).
Modernized the packaging, moving to setup.cfg etc.
Handles if the text config files incorrectly is a TZ file. (revanSZ)
The is_dst flag is wrong for Europe/Dublin on some Unix releases. I changed to another way of determining if DST is in effect or not.
Added support for Python 3.7 and 3.8. Dropped 3.5 although it still works.
Major differences since 1.5.1 .............................
When no time zone configuration can be find, tzlocal now return UTC. This is a major difference from 1.x, where an exception would be raised. This change is because Docker images often have no configuration at all, and the unix utilities will then default to UTC, so we follow that.
If tzlocal on Unix finds a timezone name in a /etc config file, then tzlocal now verifies that the timezone it fouds has the same offset as the local computer is configured with. If it doesn't, something is configured incorrectly. (Victor Torres, regebro)
Get timezone via Termux
getprop wrapper on Android. It's not officially
supported because we can't test it, but at least we make an effort.
Minor differences and bug fixes ...............................
Skip comment lines when parsing /etc/timezone. (Edward Betts)
Don't load timezone from current directory. (Gabriel Corona)
Now verifies that the config files actually contain something before reading them. (Zackary Welch, regebro)
Got rid of a BytesWarning (Mickaël Schoentgen)
Now handles if config file paths exists, but are directories.
Moved tests out from distributions
No longer treats macOS as special, but as a unix.
get_windows_info.py is renamed to update_windows_mappings.py
Windows mappings now also contain mappings from deprecated zoneinfo names. (Preston-Landers, regebro)
Dropping support for Python versions nobody uses (2.5, 3.1, 3.2), adding 3.6 Python 3.1 and 3.2 still works, 2.5 has been broken for some time.
Ayalash's OS X fix didn't work on Python 2.7, fixed that.
Ensure closing of subprocess on OS X (ayalash)
Removed unused imports (jwilk)
Closes stdout and stderr to get rid of ResourceWarnings (johnwquarles)
Updated Windows timezones (axil)
Tests failed if TZ was set in the environment. (EdwardBetts)
Replaces os.popen() with subprocess.Popen() for OS X to handle when systemsetup doesn't exist. (mckabi, cewing)
Timezones that has 3 items did not work on Mac OS X. (Marc Van Olmen)
Now doesn't fail if the TZ environment variable isn't an Olsen time zone.
Some timezones on Windows can apparently be empty (perhaps the are deleted). Now these are ignored. (Xiaokun Zhu)
Adding better support for OS X.
Added support to map from tzdata/Olsen names to Windows names. (Thanks to Benjamen Meyer).
Fixed some more cases where spaces needs replacing with underscores.
Better handling of misconfigured /etc/timezone.
Better error message on Windows if we can't find a timezone at all.
Windows 7 support.
Python 2.5 supported; because it only needed a future import.
Python 3.3 tested, it worked.
Got rid of relative imports, because I don't actually like them, so I don't know why I used them in the first place.
For each Windows zone, use the default zoneinfo zone, not the last one.