[Datetime-SIG] PEP-431/495

Akira Li 4kir4.1i at gmail.com
Tue Aug 25 17:47:30 CEST 2015


Alexander Belopolsky <alexander.belopolsky at gmail.com> writes:

>> On Aug 25, 2015, at 7:44 AM, Akira Li <4kir4.1i at gmail.com> wrote:
>> 
>> note: stdlib variant datetime.now(timezone.utc).astimezone() may fail if it
>> uses time.timezone, time.tzname internally [3,4,5] when tm_gmtoff
>> tm_zone are not available on a given platform.
>
> If this actually happens on any supported platform - please file a bug
> report.  What we do in this case is not as simplistic as you describe.

Bug-driven development is probably not the best strategy for a datetime
library ;) Tests can't catch all bugs. I've found out that astimezone()
may fail by *reading* its source and trying to *understand* what it does.

Here's the part from datetime.py [1] that computes the local timezone if
tm_gmtoff or tm_zone are not available:

  # 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)

Here's its C equivalent [2].

Python issues that I've linked in the previous message [3,4,5] demonstrate
that time.timezone and time.tzname may have wrong values and therefore
the result *tz* may have a wrong tzname. Here's an example inspired by
"incorrect time.timezone value" Python issue [4]:

  >>> from datetime import datetime, timezone
  >>> from email.utils import parsedate_to_datetime
  >>> import tzlocal # to get local timezone as pytz timezone
  >>> d = parsedate_to_datetime("Tue, 28 Oct 2013 14:27:54 +0000")
  >>> # expected (TZ=Europe/Moscow)
  ... 
  >>> d.astimezone(tzlocal.get_localzone()).strftime('%Z%z')
  'MSK+0400'
  >>> # got
  ... 
  >>> d.astimezone().strftime('%Z%z')
  'UTC+04:00+0400'

'UTC+04:00' instead of 'MSK' is not a major issue. I don't consider it a
bug because without access to the tz database stdlib can't do much
better, there always be cases when it breaks. I just use pytz instead
which does provide access to the tz database.

[1] https://github.com/python/cpython/blob/fced0e12fc510e4a6158628695774ccfd02395d3/Lib/datetime.py#L1513-L1522
[2] https://github.com/python/cpython/blob/fced0e12fc510e4a6158628695774ccfd02395d3/Modules/_datetimemodule.c#L4721-L4735
[3] http://bugs.python.org/issue1647654
[4] http://bugs.python.org/issue22752
[5] http://bugs.python.org/issue22798


More information about the Datetime-SIG mailing list