[Python-Dev] PEP 495 accepted

Nick Coghlan ncoghlan at gmail.com
Wed Sep 23 07:56:32 CEST 2015


On 23 September 2015 at 01:09, Alexander Belopolsky
<alexander.belopolsky at gmail.com> wrote:
>
> On Tue, Sep 22, 2015 at 10:55 AM, Alexander Belopolsky
> <alexander.belopolsky at gmail.com> wrote:
>>
>> On Tue, Sep 22, 2015 at 10:43 AM, Guido van Rossum <guido at python.org>
>> wrote:
>>>>
>>>> Based on the UTC/local diagram from the "Mind the Gap" section, am I
>>>> correct in thinking that the modified invariant that also covers times
>>>> in a gap is:
>>>>
>>>>     dt ==
>>>> datetime.fromtimestamp(dt.astimezone(utc).astimezone(dt.tzinfo).timestamp())
>>>>
>>>> That is, for local times that exist, the invariant "dt ==
>>>> dt.astimezone(utc).astimezone(dt.tzinfo)" holds, but for times that
>>>> don't exist, "dt.astimezone(utc).astimezone(dt.tzinfo)" will normalise
>>>> them to be a time that actually exists in the original time zone, and
>>>> that normalisation also effectively happens when calling
>>>> "dt.timestamp()".
>>>
>>>
>>> That can't be right -- There is no way any fromtimestamp() call can
>>> return a time in the gap.
>>
>>
>> I don't think Nick said that.
>
> On the second reading, it looks like Nick's second sentence contradicts his
> first.  Guido is right.  Moreover, there is no way to get a time in the gap
> as a result of any conversion including astimezone() and fromutc() in
> addition to fromtimestamp().   Such datetimes may appear if you construct
> them explicitly, use .replace() to transplant a datetime to another timezone
> (or modify other components) and in the result of datetime + timedelta
> operation.

Sorry, what I wrote in the code wasn't what I wrote in the text, but I
didn't notice until Guido pointed out the discrepancy. To get the
right universal invariant, I should have normalised the LHS, not the
RHS:

    dt.astimezone(utc).astimezone(dt.tzinfo) ==
datetime.fromtimestamp(dt.timestamp())

For unambiguous times and times in the fold, that's a subset of the
stronger invariant:

    dt == dt.astimezone(utc).astimezone(dt.tzinfo) ==
datetime.fromtimestamp(dt.timestamp())

That stronger invariant is the one that *doesn't* hold for times in
the gap, as with fold=0 they'll get normalised to use the right UTC
offset (same UTC time, nominally an hour later local time), while with
fold=1 they get mapped to an hour earlier in both UTC and local time.

Regards,
Nick.

-- 
Nick Coghlan   |   ncoghlan at gmail.com   |   Brisbane, Australia


More information about the Python-Dev mailing list