[Datetime-SIG] Local time disambiguation proposal

Tim Peters tim.peters at gmail.com
Tue Aug 4 08:14:12 CEST 2015

[Alexander Belopolsky]
> ...
> I am also working on converting my write-up [1] for publication as a
> PEP.  Please note that I have made substantial changes since my
> initial post, so if you comment on the proposal please make sure that
> you've read the latest version.
> [1]: https://github.com/abalkin/ltdf/blob/master/README.rst

Since that appears to be obsolete now, here are some comments on:



The ``replace()`` methods of the ``datetime.time`` and
``datetime.datetime`` classes will get a new keyword-only argument
called ``first`` with the default value ``True``

That's dubious:  .replace() treats all other missing arguments as
meaning "copy this attribute's current value".  I don't see why
`.first` should be different.  If there's a strong reason (I don't see
one) for

    dt2 = dt1.replace(minutes=2)

to force dt2.first to True when dt1.first is False, it would be better
to raise an exception than change the value silently.

The ``timestamp()`` method of ``datetime.datetime`` will return value
advanced by 3600 if ``self`` represents an ambiguous hour and
``first`` is False.

Are all known DST adjustments, and changes to standard UTC offsets --
in, say, zoneinfo -- exactly one hour?  For example, I read this on
the web, so it must be true:  "Lord Howe Island (Australia) advances
its clocks by half an hour in the summer" ;-)  Since I expect we
expect to support all the goofy timezones in zoneinfo, best to get
that right from the start.

The value of "first" will be ignored in all operations except those
that involve conversion between timezones.

"Involve" is vague. Subtraction and comparison can "involve"
conversion to UTC, at least conceptually, when two datetimes don't
share a tzinfo member.  It's explicitly stated later that:

Instances of ``datetime.time`` and ``datetime.datetime`` classes that
differ only by the value of their ``first`` attribute will compare as

but it's not explicitly stated that subtraction of such instances will
return timedelta(0).  If there's a reason to explicitly point out one,
then both should be mentioned, since comparison actually inherits its
behavior from subtraction.

The real reason the cases named will always compare as equal is that
they share a common tzinfo member (or both have none).  That
short-circuits the conceptional conversion to UTC before comparison.
But if you plug a workalike tzinfo member into one of them (same
timezone represented by a distinct tzinfo object), then the results of
comparison (and subtraction) _may_ change "just because" .first
differs between them.  That all depends on what .utcoffset() returns.

In the text about comparisons, I expect you're just trying to say that
.first isn't used as a tie breaker, as if datetime comparisons were
akin to tuple comparisons, comparing field by field.  But that's not
how it's done, and there's no real point to explaining how a model
that didn't apply to begin with would be affected if it had applied to
begin with ;-)

So I'd drop the text about comparisons.  But I'd add some text
explaining that, while this PEP isn't aiming at timeline arithmetic,
some cases of subtraction and comparison, which have used timeline
arithmetic all along, will return different results now due to
.utcoffset() returning different results now.  To make the reader
happy, you could even mention that these different results are also
correct now ;-)

More information about the Datetime-SIG mailing list