[Datetime-SIG] how does PEP-495 help improve dateutil, pytz timezone packages?
4kir4.1i at gmail.com
Wed Aug 26 03:20:34 CEST 2015
Alexander Belopolsky <alexander.belopolsky at gmail.com> writes:
> On Tue, Aug 25, 2015 at 7:19 PM, Akira Li <4kir4.1i at gmail.com> wrote:
>> Here's a distilled example:
>> >>> from datetime import datetime, timezone
>> >>> datetime(2013, 10, 28,
>> If you *disable tm_gmtoff attribute* then it produces UTC+04:00+0400.
>> That differs from the expected output MSK+0400, like the same code
>> demonstrates if you enable the attribute. Notice (direct quote): "if
>> tm_gmtoff or tm_zone are not available" above.
> Of course! That's why we exposed tm_gmtoff attribute in time.time_struct
> on *all platfoms* IIRC. It's been a long time, by I recall that we went to
> some great lengths to emulate tm_gmtoff by comparing the results of
> localtime calls to those of gmtime. Could it be that we missed some
> corner cases? Sure. But your "if tm_gmtoff or tm_zone are not available"
> sounds like complaining that after
>>>> del datetime.timezone
> the datetime module does not support even the UTC timezone!
Whether or not tm_gmtoff is available depends on C library. The time
module documentation says :
.. versionchanged:: 3.3
:attr:`tm_gmtoff` and :attr:`tm_zone` attributes are available on platforms
with C library supporting the corresponding fields in ``struct
i.e., tm_gmtoff, tm_zone may be absent on some platforms.
How is it similar to *del datetime.timezone* if whether or not the
attributes are available depends on platform?
I don't see how any system without a historical timezone database may
support the attributes and as far as I know C library that is used by
python.exe does not use the tz database on Windows.
To make sure that we are talking about the same thing. Here's how I've
temporarily disabled the attributes to perform the test. It *emulates*
platforms with one or both attributes missing:
diff --git a/Lib/datetime.py b/Lib/datetime.py
@@ -1507,6 +1507,7 @@
local = datetime(*localtm[:6])
# Extract TZ data if available
+ raise AttributeError
gmtoff = localtm.tm_gmtoff
zone = localtm.tm_zone
@@ -2129,7 +2130,7 @@
# pretty bizarre, and a tzinfo subclass can override fromutc() if it is.
- from _datetime import *
+ from __datetime import *
1st line forces AttributeError exception handler to execute.
2nd line disables C code that looks identical to the pure Python code.
And here's the code from the except AttributeError clause above that
I've shown in earlier messages  (C code does the same ):
# Compute UTC offset and compare with the value implied
# by tm_isdst. If the values match, use the zone name
# implied by tm_isdst.
delta = local - datetime(*_time.gmtime(ts)[:6])
dst = _time.daylight and localtm.tm_isdst > 0
gmtoff = -(_time.altzone if dst else _time.timezone)
if delta == timedelta(seconds=gmtoff):
tz = timezone(delta, _time.tzname[dst])
tz = timezone(delta)
note: as the example with datetime(2013, 10, 28,
tzinfo=timezone.utc).astimezone().strftime('%Z%z') in TZ=Europe/Moscow
demonstrates, this code  does not find the correct tz.tzname() and
therefore it is not an appropriate replacement for *tm_zone*.
The code  can't be fixed without data from the tz database.
More information about the Datetime-SIG