tasklib icon indicating copy to clipboard operation
tasklib copied to clipboard

Using of proper TZ environment

Open mowgli opened this issue 2 years ago • 8 comments

Long time now, I have troubles with tools using tasklib due to a custom setting of TZ environment variable ("CET-1", without summertime)

While python is able to work correct with that

>>> import time
>>> time.tzname
('CET', 'CET')
>>> time.strftime('%X %x %Z')
'12:22:02 10/15/21 CET'

The Approach of tzlocal using ZoneInfo is completely broken and gives exceptions and wrong results. Some of the major troubles can be patched out of tzlocal by dropping the stupid asserts but the main problem remains that ZoneInfo is not able to parse proper TZ environment.

So please use the python base structures to use timezone instead of the broken tzlocal/ZoneInfo way.

mowgli avatar Oct 15 '21 11:10 mowgli

@mowgli Do you think you'd be able to pull together a PR that improves the timezone handling for the timezones of this format? :slightly_smiling_face:

tbabej avatar Oct 15 '21 18:10 tbabej

If it would have been perl, I would have answered that question with a clear yes. But I have no real clues of python. I could help with algorithmic ideas but not coding in python.

mowgli avatar Oct 15 '21 19:10 mowgli

Got it. Well, what would really help is if you could outline in more detail what were the parts of the codebase you needed to patch out in order to get your code working with the CET-1 timezone. I could then try to put a PR together, and have it reviewed by you in terms of whether it fixes the issue at hand.

tbabej avatar Oct 15 '21 19:10 tbabej

Well, in tzlocal is a assertion that went mad. So I just patched them out. It is not really a fix but it keep most of it from breaking and throwing stack traces:

Version 2.x:

--- a/tzlocal/unix.py
+++ b/tzlocal/unix.py
@@ -84,10 +84,6 @@ def _get_localzone(_root='/'):
                     if not etctz:
                         continue
                     tz = pytz.timezone(etctz.replace(' ', '_'))
-                    if _root == '/':
-                        # We are using a file in etc to name the timezone.
-                        # Verify that the timezone specified there is actually used:
-                        utils.assert_tz_offset(tz)
                     return tz
 
         except IOError:
@@ -122,10 +118,6 @@ def _get_localzone(_root='/'):
 
                     # We found a timezone
                     tz = pytz.timezone(etctz.replace(' ', '_'))
-                    if _root == '/':
-                        # We are using a file in etc to name the timezone.
-                        # Verify that the timezone specified there is actually used:
-                        utils.assert_tz_offset(tz)
                     return tz
 
         except IOError:

Version 3.x:

--- a/tzlocal/unix.py
+++ b/tzlocal/unix.py
@@ -90,10 +90,6 @@ def _get_localzone(_root='/'):
                     if not etctz:
                         continue
                     tz = ZoneInfo(etctz.replace(' ', '_'))
-                    if _root == '/':
-                        # We are using a file in etc to name the timezone.
-                        # Verify that the timezone specified there is actually used:
-                        utils.assert_tz_offset(tz)
                     return tz
 
         except (IOError, UnicodeDecodeError):
@@ -128,10 +124,6 @@ def _get_localzone(_root='/'):
 
                     # We found a timezone
                     tz = ZoneInfo(etctz.replace(' ', '_'))
-                    if _root == '/':
-                        # We are using a file in etc to name the timezone.
-                        # Verify that the timezone specified there is actually used:
-                        utils.assert_tz_offset(tz)
                     return tz
 
         except (IOError, UnicodeDecodeError) as e:

Version 1.5.1 was a last working version of tzlocal. Afterwards it gets more and more bad.

However, I do still not understand, why this is implemented that broken way and not using the python standard methods from time import which seems to do it the right way.

mowgli avatar Oct 15 '21 21:10 mowgli

Ah yes, even the 1.5.1 version was a bit wrong:

--- unix.py.orig        2020-03-05 15:31:48.600637137 +0100
+++ unix.py     2020-03-05 15:32:03.720637570 +0100
@@ -105,7 +105,7 @@
     if os.path.exists(tzpath) and os.path.islink(tzpath):
         tzpath = os.path.realpath(tzpath)
         start = tzpath.find("/")+1
-        while start is not 0:
+        while start != 0:
             tzpath = tzpath[start:]
             try:
                 return pytz.timezone(tzpath)

mowgli avatar Oct 15 '21 21:10 mowgli

There is another information, It seems that tzlocal changed its API between 2 and 3. And the later one is incompatible at all with tasklib.

mowgli avatar Oct 21 '21 09:10 mowgli

Is this true for the newest tasklib release? I was under the impression we are now compatible with tzlocal 3.x.

tbabej avatar Oct 21 '21 11:10 tbabej

I don't know. I use tasklib 2.3.4-r1 in gentoo. Devuan uses 2.4.3 but I have tzlocal on hold on that system with version 1.5.1 as this version had have only little trouble with python3 (see above).

mowgli avatar Oct 21 '21 12:10 mowgli