[Datetime-SIG] how does PEP-495 help improve dateutil, pytz timezone packages?
Akira Li
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,
>> tzinfo=timezone.utc).astimezone().strftime('%Z%z')
>>
>> 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 [1]:
.. versionchanged:: 3.3
:attr:`tm_gmtoff` and :attr:`tm_zone` attributes are available on platforms
with C library supporting the corresponding fields in ``struct
tm``.
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.
[1] https://docs.python.org/3.4/library/time.html#time.struct_time
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
--- a/Lib/datetime.py
+++ b/Lib/datetime.py
@@ -1507,6 +1507,7 @@
local = datetime(*localtm[:6])
try:
# Extract TZ data if available
+ raise AttributeError
gmtoff = localtm.tm_gmtoff
zone = localtm.tm_zone
except AttributeError:
@@ -2129,7 +2130,7 @@
# pretty bizarre, and a tzinfo subclass can override fromutc() if it is.
try:
- from _datetime import *
+ from __datetime import *
except ImportError:
pass
else:
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 [2] (C code does the same [3]):
# 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])
else:
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 [4] does not find the correct tz.tzname() and
therefore it is not an appropriate replacement for *tm_zone*.
The code [4] can't be fixed without data from the tz database.
[2] https://mail.python.org/pipermail/datetime-sig/2015-August/000471.html
[3] https://github.com/python/cpython/blob/fced0e12fc510e4a6158628695774ccfd02395d3/Modules/_datetimemodule.c#L4721-L4735
[4] https://github.com/python/cpython/blob/fced0e12fc510e4a6158628695774ccfd02395d3/Lib/datetime.py#L1513-L1522
More information about the Datetime-SIG
mailing list