Paul G added the comment:

I've never written a "What's New" before, but here are the main things I took 
away from implementing a PEP 495-compliant tzinfo class:

- The `fold` attribute is the SECOND occurrence of the time, not the first 
occurrence of the time. In my first pass solution of this, I had this inverted, 
so I would say it's worth making it very clear which is which, maybe with an 
example (I'm using full zone names here like those returned by 
`dateutil.tz.tzwin`):

    >>> datetime(2011, 11, 6, 1, 30, fold=0, tzinfo=US_EASTERN).tzname()
    'Eastern Daylight Time'
    >>> datetime(2011, 11, 6, 1, 30, fold=1, tzinfo=US_EASTERN).tzname()
    'Eastern Standard Time'

- Because the default for "fold" is 0, the default for "unspecified" fold has 
changed from being on the STD side to being on the DST side:

    >>> datetime(2011, 11, 6, 1, 30, tzinfo=US_EASTERN_NO495).tzname()
    'EST'
    >>> datetime(2011, 11, 6, 1, 30, tzinfo=US_EASTERN_PEP495).tzname()
    'EDT'

- It is now best practices to implement your own `fromutc()` (I got the 
impression that in the past it was encouraged that you generally just wrote a 
`utcoffset()` and `dst()` function.

- Comparisons of datetimes have changed such that inter-zone comparisons 
representing the same wall time and offset will now fail during ambiguous times 
(depending on the resolution of #28601, the exact semantics of what is an 
inter-zone comparison should be clarified):

    >>> dt1 = datetime(2016, 11, 6, 1, 30, fold=1, tzinfo=US_EASTERN)
    >>> dt2 = datetime(2016, 11, 6, 1, 30, fold=0, tzinfo=US_CENTRAL)
    >>> dt1 == dt2
    False

I think the remainder of my insights would have to do with 
backwards-compatibility and I'm not sure how much relevance they have to 
"What's New".

With regards to the documentation, here are my notes:

- One thing that should be made more clear is that arithmetic operations wipe 
out the `fold` attribute - this behavior and the reasoning behind it should 
probably be clear in the section on datetime operations, because I think people 
will be confused by this:

   >>> from datetime import datetime, timedelta
   >>> from dateutil import tz
   >>> dt = datetime(2011, 11, 6, 1, 30, fold=1, tz=gettz('US/Eastern')
   >>> dt.tzname()
   'EST'
   >>> (dt + timedelta(minutes=1)).tzname()
   'EDT'

- Not related to the changes in 3.6, but it might also be worth clarifying that 
`datetime.astimezone()` with no arguments returns a datetime with a fixed 
offset zone, NOT the local zone (it's somewhat clear, but it could be more 
explicit):

   >>> dt.astimezone().tzname()
   2011-11-06 01:30:00-5:00
   >>> dt.astimezone() - timedelta(hours=5)
   2011-11-05 20:30:00-05:00
   >>> dt.astimezone(tz.tzlocal())
   2011-11-06 01:30:00-5:00
   >>> dt.astimezone(tz.tzlocal()) - timedelta(hours=5)
   2011-11-05 20:30:00-04:00

- In the section on "working with datetime objects", GMT1 and GMT2 objects 
don't support the `fold` attribute. That might be confusing (though there are 
fold-aware tzinfo objects later in the documentation).

- In the section on time.tzname(), the example defines its own GMT1 time zone. 
It might be clearer to just define GMT1 = datetime.timezone(timedelta(hours=1), 
"Europe/Prague') rather than create a new fixed offset tzinfo.

- The "most implementations of dst() will probably look like one of these two" 
section should be updated to reflect `fold`, maybe something like this:

    def dst(self, dt):
        # Code to set dston and dstoff to the time zone's DST
        # transition times based on the input dt.year, and expressed
        # in standard local time.

        dt_naive = dt.replace(tzinfo=None)
        if dston <= dt_naive < dstoff:
            if dt_naive < dston + timedelta(hours=1) and dt.fold:
                return timedelta(0)
            else:
                return timedelta(hours=1)
        else:
            return timedelta(0)

- The tzinfo.fromutc(dt) documentation suggests that this method is capable of 
handling non-fixed offset zones.  Per #28602, it seems that it should be made 
clear that all zones implementing `fold` support should implement their own 
`fromutc` method, as there is a deliberate bug in the algorithm when folds are 
supported.

- This may be slightly confusing: "Note that the datetime instances that differ 
only by the value of the fold attribute are considered equal in comparisons.", 
because when I first read this, I assumed it meant that datetime(2011, 11, 6, 
1, 30, tzinfo=US_EASTERN) == datetime(2011, 11, 6, 1, 30, fold=1, 
tzinfo=US_EASTERN), but in fact it either means that *unambiguous* datetimes 
that differ only by their `fold` attribute are equal, ambiguous datetimes with 
a fold-aware tzinfo attached will return a different utcoffset() and thus not 
compare equal.

- I found this slightly confusing, under the "dateutil.tz" heading: "The 
standard library has timezone class for handling arbitrary fixed offsets from 
UTC and timezone.utc as UTC timezone instance." Since dateutil.tz does not 
provide a `timezone` class, I thought it was a mistake, but I think that that 
text should actually be *above* the "dateutil.tz" header, since it refers to 
the Python standard library.

- On the subject of the dateutil.tz callout (thanks for that, by the way), it 
may be worth noting that while pytz only provides IANA zones, dateutil.tz also 
provides other zones, such as zones parsed from GNU TZ strings and a wrapper 
around the Windows time zone interface. (This latter is useful, by the way, 
because of a bug in Microsoft CRT that makes it so that time.localtime will not 
reflect changes in system time zone without a new instance of Python - see 
#10634. dateutil.tz.tzwinlocal() uses the native Windows interface and is not 
subject to this bug, though dateutil.tz.tzlocal(), as a wrapper around time, 
is).

----------

_______________________________________
Python tracker <rep...@bugs.python.org>
<http://bugs.python.org/issue28641>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to