Reputation: 25564
Checking out the zoneinfo
module in Python 3.9, I was wondering if it also offers a convenient option to retrieve the local time zone (OS setting) on Windows.
On GNU/Linux, you can do
from datetime import datetime
from zoneinfo import ZoneInfo
naive = datetime(2020, 6, 11, 12)
aware = naive.replace(tzinfo=ZoneInfo('localtime'))
but on Windows, that throws
ZoneInfoNotFoundError: 'No time zone found with key localtime'
so would I still have to use a third-party library? e.g.
import time
import dateutil
tzloc = dateutil.tz.gettz(time.tzname[time.daylight])
aware = naive.replace(tzinfo=tzloc)
Since time.tzname[time.daylight]
returns a localized name (German in my case, e.g. 'Mitteleuropäische Sommerzeit'), this doesn't work either:
aware = naive.replace(tzinfo=ZoneInfo(tzloc))
Any thoughts?
p.s. to try this on Python < 3.9, use backports
(see also this answer):
pip install backports.zoneinfo
pip install tzdata # needed on Windows
Upvotes: 12
Views: 16196
Reputation: 25564
While astimezone(None)
is convenient, sometimes you might want to get the IANA name of the time zone your OS is configured to use. Be careful though, Windows does not use the IANA database; a mapping is required from "Windows time zone" to IANA identifier. That mapping might be wrong, see Philip Couling's answer below.
Version 4 of tzlocal
will also use zoneinfo
for that whilst maintaining compatibility with pytz
through the deprecation shim:
>>> import tzlocal
>>> print(tzlocal.get_localzone())
Europe/Berlin
>>> print(repr(tzlocal.get_localzone()))
_PytzShimTimezone(zoneinfo.ZoneInfo(key='Europe/Berlin'), 'Europe/Berlin')
[update] With version 5, the pytz deprecation shim is removed, see also tzlocal's readme:
>>> print(tzlocal.get_localzone())
Europe/Berlin
>>> print(repr(tzlocal.get_localzone()))
zoneinfo.ZoneInfo(key='Europe/Berlin')
Upvotes: 6
Reputation: 14903
That's understandable; the topic is maddeningly complex, even for such trivially simple questions!
The misunderstanding here is to believe zoneinfo
can be related to MS Window's local timezones. It can't! They are two completely different things, even if they look alike:
Jon Skeet discusses it here: IANA to Windows timezone mapping. The problem is not just about the names of the timezones, but their actual meaning.
Timezones don't really exist. The more you try to prove they exist, the more you find they really really don't exist.
Some humans observe different time on the clock to other humans. There have been attempts to catalogue which humans observe which times and how these all fit together. But these are political decisions and sometimes politics gets very messy.
When you try to catalog which humans observe which timezone, you will find cases were there is no right answer. Eg: Lebinon in 2023.
The main problem is that IANA (used by zoneinfo
) is a seperate database to the one used by MS Windows. While you can find many mappings between the two they don't necessarily coordinate with each other and so can really disagree on offsets.
Really dangerously you can find mappings that look like they match but suddenly and unexpectly disagree, so unless you are going to very carefully handle the conversion yourself, you shouldn't try to get the IANA name for an MS Windows configured timezone.
Upvotes: 5
Reputation: 241573
You don't need to use zoneinfo to use the system local time zone. You can simply pass None
(or omit) the time zone when calling datetime.astimezone
.
From the docs:
If called without arguments (or with
tz=None
) the system local timezone is assumed. The.tzinfo
attribute of the converted datetime instance will be set to an instance of timezone with the zone name and offset obtained from the OS.
Thus:
from datetime import datetime
naive = datetime(2020, 6, 11, 12)
aware = naive.astimezone()
Upvotes: 10