[Datetime-SIG] Timeline arithmetic?

Carl Meyer carl at oddbird.net
Tue Sep 8 21:34:23 CEST 2015

```> [Tim]
>>>>> An aware datetime _is_ a <naive datetime,
>>>>> tzinfo> pair, and there's a natural bijection between naive datetimes
>>>>> and POSIX timestamps (across all instants both can represent).
>
>  [Carl]
>>>> I don't understand this, and I suspect it's at the heart of our
>>>> misunderstanding. I would say there are many possible bijections ....
>
>  [Tim]
>>> "Natural" bijection.  I gave you very simple Python code implementing
>>> that bijection already.  A naive datetime represents an instant in the
>>> proleptic Gregorian calendar.
>
> [Carl]
>> What is your definition of "instant" here?

[Tim]
> I didn't need one - Occam's Razor again ;-)  To establish a bijection,
> all that's required is to show that a proposed function meets all the
> formal requirements...  "Represents an
> instance" was just vague English motivation for what followed.

Of course. I never expressed any doubt that you had established _a_
bijection. It was the motivation I was trying to understand.

>> I don't think a naive datetime represents an instant at all;
>
> Fine by me - and by Python.  Also fine if you _never_ use a naive datetime.
>
>> it represents a range of possible instants,
>
> Heh - I see you haven't defined what _you_ mean by "instant".

I already gave my definition earlier in this thread. It's borrowed from
NodaTime/JodaTime: an instant is a unique and unambiguous point on a
single global non-relativistic monotonic time line. Since I don't care
about leap seconds, this definition is satisfied equally well for my
purposes by a POSIX timestamp or a UTC datetime, among many other
possible representations.

I find this definition of instant _useful_ because it means that all
instants, no matter their representations, are always convertible to
integers on the same scale. That's not true of naive datetimes, without
making an additional assumption of timezone.

>  When
> you do, please be sure it's consistent with what POSIX says here too:
>
>     The relationship between the actual time of day and the current
>     value for seconds since the Epoch is unspecified.
>
>     How any changes to the value of seconds since the Epoch are
>     made to align to a desired relationship with the current actual time
>     is implementation-defined. As represented in seconds since the
>     Epoch, each and every day shall be accounted for by exactly
>     86400 seconds.

AFAICT that's just a bit of beating around the bush about not supporting
leap seconds. I don't care :-)

> While you're at it, define a clean model in which all that makes a
> lick of sense to a casual user ;-)

Actually, I think Model A _is_ such a clean model (if we can presume
that the casual user in question also doesn't care about leap seconds or
relativistic effects). I've taught many Python users how to use pytz,
and my experience has been that the concept of a single global monotonic
timeline, where all aware datetimes are simply variant spellings of some
unambiguous point on that timeline, but (other than in their
representation as a Gregorian date/time) behave the same no matter which
timezone you spell them in, is quite easy to explain and grasp, even for
people who've never worked with timezones before.

Part of my dismay in this thread has been realizing now that I've
mis-educated all these users about how datetime is really supposed to
work :-) Like Stuart, I'm a bit concerned that a whole lot of pytz users
are going to be very confused if or when they try to switch to PEP 495

I think in some ways Model B is really more powerful than Model A,
because it lets you work in any number of different "local time" models,
rather than requiring that you always work on the same single global
timeline. And there are definitely cases where you need that.

> The "so what?", in context, was to tweak Guido about saying an aware
> datetime is fundamentally different from a <timestamp, tzinfo> pair,
> despite that the space of such pairs is isomorphic to the space of
> aware datetimes (which _is_ the space of <naive datetime, tzinfo>
> pairs) under the natural naive_datetime <-> timestamp bijection.
>
> Why is that setting _you_ off?  Guido handled it just fine ;-)

Heh. Just the urge to understand things, that's all. I'm just slower
than Guido :-) but I think I get your point now; it was a narrower point
than I'd realized. <posix-timestamp, tz> is only "fundamentally
different" from <naive-datetime, tz> in that they imply different mental
models about what they are supposed to represent; mathematically they
are no different.

>> Under what circumstances is it reasonable to make that assumption
>
> Any use case where it's convenient   That's up to the user. not me -
> or you.  For example, before Python grew its builtin
> datetime.timezone.utc implementation of a UTC class, I routinely used
> naive datetimes I thought of as being in UTC.  I was too lazy to
> remember where I hid my own UTC class.  No problem.

Sure, of course. As a pytz user, I'm forced to do the same thing (use
naive datetimes and track an implied timezone separately) anytime I need
to work in a "local clock time" model.

>> Rather than saying "a naive datetime simply doesn't correspond to
>> any particular POSIX timestamp;  they aren't comparable at all unless
>> you have additional information," which is what I'd say.
>
> I'm starting to suspect you didn't design datetime ;-)  In context, I
> was replying to Guido, who was talking about Python.  In Python's
> datetime, naive datetimes are comparable.   Naive time has no
> _concept_ of time zone.  Naive datetimes nevertheless have a  notion
> of total order, which is isomorphic to the POSIX timestamp notion of
> total order under the natural bijection.  Likewise for arithmetic,
> etc.  There's nothing "wrong" about exploiting any of that when it's
> convenient.

This is simply a mis-understanding. I certainly do consider naive
datetimes comparable to other naive datetimes, and I'm well aware (and
glad) that Python does too. The referent of "they" above was "naive
datetimes and POSIX timestamps." I don't consider those comparable _to
timezone of the naive datetime. And Python agrees.

>> I mean, I certainly hope you wouldn't want datetime to make `utcdt -
>> naivedt` a defined operation where it's assumed the naive datetime is UTC.
>
> Certainly not.  That _would_ be wrong ;-)

Violent agreement again in the end once again, then...

Carl

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: OpenPGP digital signature
URL: <http://mail.python.org/pipermail/datetime-sig/attachments/20150908/2bd65107/attachment.sig>
```