[Datetime-SIG] pytz vs. PEP 495 Was: PEP-431/495

Alexander Belopolsky alexander.belopolsky at gmail.com
Mon Aug 24 19:16:15 CEST 2015


It is quite possible that we have a communication failure because I am not
sufficiently familiar with the way pytz works.  Let's use this new thread
to discuss what is common and what is different between pytz and PEP 495
approaches to disambiguating folds and dealing with gaps.

Let's keep any kind of arithmetic issues out of this thread and stay within
the scope of PEP 495.


On Mon, Aug 24, 2015 at 9:56 AM, Stuart Bishop <stuart at stuartbishop.net>
wrote:

> If a user calls localize(is_dst=None), AmbiguousTImeError and
> NonExistantTimeError exceptions may be raised, but by default
> exceptions are not raised.
>

>From your recent example, naive datetime(2004, 4, 4, 2) falls in US/Eastern
spring-forward gap:

>>> dt = datetime(2004, 4, 4, 2)

Here is what I get using pytz.timezone:

>>> EasternTZ = pytz.timezone('US/Eastern')
>>> EasternTZ.localize(dt).isoformat()
'2004-04-04T02:00:00-05:00'
>>> EasternTZ.localize(dt, is_dst=-1).isoformat()
'2004-04-04T02:00:00-04:00'
>>> EasternTZ.localize(dt, is_dst=0).isoformat()
'2004-04-04T02:00:00-05:00'
>>> EasternTZ.localize(dt, is_dst=1).isoformat()
'2004-04-04T02:00:00-04:00'
>>> EasternTZ.localize(dt, is_dst=10).isoformat()
'2004-04-04T02:00:00-04:00'
>>> EasternTZ.localize(dt, is_dst=None).isoformat()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File ".../pytz/tzinfo.py", line 327, in localize
    raise NonExistentTimeError(dt)
pytz.exceptions.NonExistentTimeError: 2004-04-04 02:00:00

Note that in all non-error cases, you get the invalid "02:00" time in the
output.

PEP 495 takes a different approach:

>>> from test.datetimetester import Eastern2
>>> datetime(2004, 4, 4, 2, first=True,
tzinfo=Eastern2).astimezone().isoformat()
'2004-04-04T03:00:00-04:00'
>>> datetime(2004, 4, 4, 2, first=False,
tzinfo=Eastern2).astimezone().isoformat()
'2004-04-04T01:00:00-05:00'

A post-PEP 495 timezone conversion faced with a missing time is required to
return a valid time.  This is similar to the way C mktime works in most
implementations.  If you give it a struct tm representing a time from a DST
gap - it will "normalize" it by changing tm_hour up or down depending on
the tm_isdst value.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/datetime-sig/attachments/20150824/6ce5559a/attachment.html>


More information about the Datetime-SIG mailing list