regebro / tzlocal

A Python module that tries to figure out what your local timezone is
MIT License
184 stars 58 forks source link

Multiple Conflicting Timezones for Etc/UTC #127

Closed mudinthewater closed 1 year ago

mudinthewater commented 2 years ago

Python and tzlocal version: tzlocal version 4.2 Python version Python 3.8.5

OS info: NAME="Amazon Linux" VERSION="2" ID="amzn" ID_LIKE="centos rhel fedora" VERSION_ID="2" PRETTY_NAME="Amazon Linux 2" ANSI_COLOR="0;33" CPE_NAME="cpe:2.3:o:amazon:amazon_linux:2" HOME_URL="https://amazonlinux.com/"

Stack trace:

Python 3.8.5 (default, Feb 18 2021, 01:24:20) [GCC 7.3.1 20180712 (Red Hat 7.3.1-12)] on linux Type "help", "copyright", "credits" or "license" for more information.

import tzlocal l=tzlocal.get_localzone() Traceback (most recent call last): File "", line 1, in File "/usr/local/lib/python3.8/site-packages/tzlocal/unix.py", line 203, in get_localzone _cache_tz = _get_localzone() File "/usr/local/lib/python3.8/site-packages/tzlocal/unix.py", line 165, in _get_localzone tzname = _get_localzone_name(_root) File "/usr/local/lib/python3.8/site-packages/tzlocal/unix.py", line 144, in _get_localzone_name raise utils.ZoneInfoNotFoundError(message) tzlocal.utils.ZoneInfoNotFoundError: 'Multiple conflicting time zone configurations found:\n/etc/sysconfig/clock: Etc/UTC\n/etc/localtime is a symlink to: UTC\nFix the configuration, or set the time zone in a TZ environment variable.\n'

/etc/localtime link:

ll /etc/localtime lrwxrwxrwx 1 root root 27 Apr 5 00:09 /etc/localtime -> /usr/share/zoneinfo/Etc/UTC

Etc/UTC is not a simlink: ll /usr/share/zoneinfo/Etc/UTC -rw-r--r-- 8 root root 127 Feb 11 19:04 /usr/share/zoneinfo/Etc/UTC

and contents of clock file:

cat /etc/sysconfig/clock ZONE="Etc/UTC" UTC="true"

When ZONE is set to "Etc/UTC" the stack trace appears. When it's set to just "UTC" tzlocal appears to be fine with it.

mudinthewater commented 2 years ago

Woraround is to set ZONE and localtime simlink to /usr/share/zoneinfo/UTC, or set ZONE to just UTC and use either UTC or Etc/UTC.

mudinthewater commented 1 year ago

Okay decided to take another look at this:

System still the same: contents of /etc/sysconfig/clock:

ZONE="Etc/UTC" UTC="true" /etc/localtime -> /usr/share/zoneinfo/Etc/UTC

So by default our Zone is "Etc/UTC". Note that "There is NO difference between UTC and Etc/UTC time zones."

Contents of found_configs in unix.py at line 124. {'/etc/sysconfig/clock':` 'Etc/UTC', '/etc/localtime is a symlink to': 'UTC'}

However, /etc/localtime isn't a simlink to "UTC" it's a simlink to Etc/UTC, which is consistent with the config file.

So the issue is in unix.py at line 117. Because it checks a while loop, and both "UTC" and "Etc/UTC" exist, it will find both. However, the found config only lists the last one found because it replaces the contents each time through the loop. Printing the contents of found_configs as it goes through the loop yields this: {'/etc/sysconfig/clock': 'Etc/UTC', '/etc/localtime is a symlink to': 'Etc/UTC'} {'/etc/sysconfig/clock': 'Etc/UTC', '/etc/localtime is a symlink to': 'UTC'} The first one is correct, but the second is wrong.

This behavior would also apply to GMT, and a few other timezones that exist in both the /usr/share/zoneinfo/ and the /usr/share/zoneinfo/Etc folders.

A break added to the while loop added after 119 should resolve this by making the configuration represent the first valid timezone relative to /etc/localtime. Alternately, but it would require more work, the while loop could be reworked to include all valid timezones in the path that's simlinked from /etc/localtime, but I don't see any added value there, as the one of interest should always be the first relative path timezone.

Thoughts @regebro?