Rocksolid Light

Welcome to novaBBS (click a section below)

mail  files  register  newsreader  groups  login

Message-ID:  

"One Architecture, One OS" also translates as "One Egg, One Basket".


devel / comp.lang.python / Re: Pre-Pre-PEP: The datetime.timedeltacal class

SubjectAuthor
o Re: Pre-Pre-PEP: The datetime.timedeltacal classPeter J. Holzer

1
Re: Pre-Pre-PEP: The datetime.timedeltacal class

<mailman.148.1650183362.20749.python-list@python.org>

  copy mid

https://www.novabbs.com/devel/article-flat.php?id=17903&group=comp.lang.python#17903

  copy link   Newsgroups: comp.lang.python
Path: i2pn2.org!i2pn.org!news.swapon.de!fu-berlin.de!uni-berlin.de!not-for-mail
From: hjp-pyt...@hjp.at (Peter J. Holzer)
Newsgroups: comp.lang.python
Subject: Re: Pre-Pre-PEP: The datetime.timedeltacal class
Date: Sun, 17 Apr 2022 10:15:54 +0200
Lines: 194
Message-ID: <mailman.148.1650183362.20749.python-list@python.org>
References: <20220416173551.fk6voaa3o25iuewm@hjp.at>
<CAPTjJmqdd4Qwrr72h4Y28dhZ_JXa9VSJFWmHXt4KfD-eNMwOTA@mail.gmail.com>
<20220417081554.wewkrvvl2xmiygsm@hjp.at>
Mime-Version: 1.0
Content-Type: multipart/signed; micalg=pgp-sha512;
protocol="application/pgp-signature"; boundary="dowxcj3he7e73cif"
X-Trace: news.uni-berlin.de 7FgH7VMZs4fD/DzWd9wrTQ0JGOEOywcsDVA3XIe4eHVA==
Return-Path: <hjp-python@hjp.at>
X-Original-To: python-list@python.org
Delivered-To: python-list@mail.python.org
Authentication-Results: mail.python.org; dkim=none reason="no signature";
dkim-adsp=none (unprotected policy); dkim-atps=neutral
X-Spam-Status: OK 0.000
X-Spam-Evidence: '*H*': 1.00; '*S*': 0.00; 'argument': 0.04; '(e.g.':
0.05; '2022': 0.05; 'content-type:multipart/signed': 0.05;
'happened': 0.07; 'sun,': 0.07; 'utc': 0.07; 'angelico': 0.09;
'anyway,': 0.09; 'april.': 0.09; 'compute': 0.09; 'content-
type:application/pgp-signature': 0.09; 'datetime': 0.09;
'filename:fname piece:asc': 0.09; 'filename:fname
piece:signature': 0.09; 'filename:fname:signature.asc': 0.09;
'float': 0.09; "hasn't": 0.09; 'hour,': 0.09; 'minute,': 0.09;
'obviously': 0.09; 'shift': 0.09; "shouldn't": 0.09; 'smaller':
0.09; 'subject:class': 0.09; 'typically': 0.09; 'yes.': 0.09;
'"add': 0.16; '"computer': 0.16; '"creative': 0.16; '"in': 0.16;
'"there': 0.16; '(unless': 0.16; '__/': 0.16; 'arbitrary': 0.16;
'arguments': 0.16; 'arithmetic': 0.16; 'challenge!"': 0.16;
'constructor': 0.16; 'daylight': 0.16; 'delta': 0.16; 'from:addr
:hjp-python': 0.16; 'from:addr:hjp.at': 0.16; 'from:name:peter j.
holzer': 0.16; 'hjp@hjp.at': 0.16; 'holzer': 0.16; 'hours,': 0.16;
'instead.': 0.16; 'objects.': 0.16; 'odd': 0.16; 'php': 0.16;
'reality.': 0.16; 'right.': 0.16; 'seconds.': 0.16; 'semantics':
0.16; 'shorter': 0.16; 'sounds': 0.16; 'stross,': 0.16;
'subject:Pre': 0.16; 'subject:skip:d 20': 0.16; 'time",': 0.16;
'troll': 0.16; 'unlikely': 0.16; 'url-ip:212.17.106.137/32': 0.16;
'url-ip:212.17.106/24': 0.16; 'url-ip:212.17/16': 0.16; 'url:hjp':
0.16; 'wikipedia': 0.16; '|_|_)': 0.16; 'wrote:': 0.16; 'problem':
0.16; "can't": 0.17; "aren't": 0.19; 'to:addr:python-list': 0.20;
'weeks': 0.23; "i'd": 0.24; 'actual': 0.25; 'saying': 0.25;
'cities': 0.26; 'months,': 0.26; 'object': 0.26; "isn't": 0.27;
'local': 0.27; 'function': 0.27; 'done': 0.28; 'chris': 0.28;
'expect': 0.28; 'mostly': 0.28; 'sense': 0.28; 'error': 0.29;
'takes': 0.31; 'annual': 0.31; 'putting': 0.31; 'think': 0.32;
"doesn't": 0.32; '"this': 0.32; 'issues.': 0.32; 'minutes,': 0.32;
'same,': 0.32; 'specified': 0.32; 'split': 0.32; 'weeks,': 0.32;
"wouldn't": 0.32; 'but': 0.32; "i'm": 0.33; 'there': 0.33;
'year,': 0.33; 'same': 0.34; 'mean': 0.34; 'header:In-Reply-To:1':
0.34; 'years': 0.65; 'received:userid': 0.66; 'day': 0.66;
'decided': 0.67; 'back': 0.67; 'time,': 0.67; 'that,': 0.67;
'matter': 0.68; 'days,': 0.69; 'net': 0.69; 'result,': 0.69;
'stores': 0.69; 'url-ip:212/8': 0.69; 'varying': 0.69; 'times':
0.69; 'reach': 0.69; 'subject:The': 0.70; 'longer': 0.71; 'free':
0.72; "you'll": 0.73; 'zone': 0.76; 'quick': 0.77; 'database':
0.80; 'extra': 0.84; 'amount,': 0.84; 'cleaner': 0.84;
'direction.': 0.84; 'exactly.': 0.84; 'exceptions': 0.84; 'hold,':
0.84; 'leap': 0.84; 'minutes?': 0.84; 'received:at': 0.84;
'represented': 0.84; 'savings': 0.84; 'summer,': 0.84; 'utc+2':
0.84; 'weird': 0.84; 'opposite': 0.91; '30th': 0.95
Mail-Followup-To: python-list@python.org
Content-Disposition: inline
In-Reply-To: <CAPTjJmqdd4Qwrr72h4Y28dhZ_JXa9VSJFWmHXt4KfD-eNMwOTA@mail.gmail.com>
X-BeenThere: python-list@python.org
X-Mailman-Version: 2.1.39
Precedence: list
List-Id: General discussion list for the Python programming language
<python-list.python.org>
List-Unsubscribe: <https://mail.python.org/mailman/options/python-list>,
<mailto:python-list-request@python.org?subject=unsubscribe>
List-Archive: <https://mail.python.org/pipermail/python-list/>
List-Post: <mailto:python-list@python.org>
List-Help: <mailto:python-list-request@python.org?subject=help>
List-Subscribe: <https://mail.python.org/mailman/listinfo/python-list>,
<mailto:python-list-request@python.org?subject=subscribe>
X-Mailman-Original-Message-ID: <20220417081554.wewkrvvl2xmiygsm@hjp.at>
X-Mailman-Original-References: <20220416173551.fk6voaa3o25iuewm@hjp.at>
<CAPTjJmqdd4Qwrr72h4Y28dhZ_JXa9VSJFWmHXt4KfD-eNMwOTA@mail.gmail.com>
 by: Peter J. Holzer - Sun, 17 Apr 2022 08:15 UTC
Attachments: signature.asc (application/pgp-signature)

On 2022-04-17 06:08:54 +1000, Chris Angelico wrote:
> On Sun, 17 Apr 2022 at 03:37, Peter J. Holzer <hjp-python@hjp.at> wrote:
> > Datetime arithmetic in the real world is typically not done in seconds,
> > but in calendaric units: Hours, days, weeks, months, years, ...
> > The problem is that several of these have varying lengths:
> >
> > * 1 minute may be 60 or 61 seconds (theoretically also 59, but that
> > hasn't happened yet).
> > * 1 day can be 23, 24 or 25 hours (unless you are in Troll, Antarctica,
> > where it's even weirder).
>
> I think Troll still only has days that consist of 23-25 hours; the
> weird part is that they move their clocks forward for Oslo's summer,
> which is their winter.

According to Wikipedia they switch between UTC+2 and UTC+0, so the
switchover days would be 22 and 26 hours, respectively.

> > Therefore a new class (provisionally called timedeltacal, because it is
> > calendaric, not absolute) should be added to datetime:
> >
> > Internally it stores months, days, seconds and microseconds as ints.
> >
> > The seconds and microseconds split is mostly for compatibility with
> > datetime and timedelta. We could store seconds as a float instead.
> >
> > We don't store minutes since leap seconds aren't usually represented in
> > "computer time", so they are unlikely to be useful in a timedeltacal
> > object.
> >
> > Days are stored since they aren't a fixed multiple of any smaller unit.
> > Months are stored since they aren't a fixed multiple of any smaller unit.
> >
> > Hours, weeks and years aren't stored since they are always 60 minutes, 7
> > days and 12 months respectively.
>
> It sounds like you're planning for annual DST changes, but what about
> other shifts? What about when a location adopts standard time, which
> could change their UTC offset (yes, I'm aware that most places adopted
> standard time before UTC was a thing, but we still usually call it a
> UTC offset rather than messing with GMT-UTC changeover) by an
> arbitrary amount, even minutes?

Yes, I think you are right. I first thought it wouldn't matter because
you'd have to look it up in the database anyway, but that's a
non-sequitur. Clearly, when you cities switched from local times to
timezones, one hour had to be longer or shorter than 3600 seconds.
Similarily if India decided to switch to a whole-hour offset, then they
would have one hour of 30 or 90 minutes.

> It might be cleaner to simply have all of the arguments that datetime
> has: year, month, day, hour, minute, second, microsecond (with the
> possibility of merging second/usec into a single float).

Yup.

> > When adding a timedeltacal object to a datetime, the fields are added
> > from most to least significant: First a new date is computed by
> > advancing the number of months specified [TODO: Research how other
> > systems handle overflow (e.g. 2022-01-31 + 1 month: 2022-02-31 doesn't
> > exist)]
>
> Quick test in Pike:
[...]
> Subtracting seventeen days from today gets us to the 31st of March,
> and adding one month to that gives us the 30th of April. Subtracting
> eighteen days gets us to the 30th of March, and adding a month to that
> _also_ gives us the 30th of April.

Same for PostgreSQL.

> > then advance the number of days. Finally add the number of
> > seconds and microseconds, taking into accout daylight savings time
> > switches if the datetime is time zone aware.
>
> Here's the local DST switchover:
[results I expected]

> > Subtracting a timedeltacal object from a datetime is the same, just in
> > the opposite direction.
> >
> > Note that t + d - d is in general not equal to t.
>
> By "in general", do you mean "there will be some odd exceptions", or
> "this is usually going to be unequal"?

The former.

> For instance, going back to the month boundary case, since it's not
> possible for "add one month" from two different dates to give the same
> result, obviously subtracting a month from that result can't give both
> the originals. But for the most part, I would expect t + d - d to be
> equal to t, modulo rounding error and possible DST corrections.
> Crossing a DST boundary shouldn't break this pattern; only landing in
> the actual gap/fold should cause issues.
> Is that the intention?

Yes, exactly.

> > We can't cnange the semantics of datetime - datetime, so there must be a
> > function to compute the difference between to datetimes as a
> > timedeltacal. It could be a method on datetime (maybe t.sub(u) for t-u
> > like in Go) or a constructor which takes two datetime objects.
> >
> > In any case I think that u + (t - u) == t should hold. [TODO: Check that
> > this is possible]
> >
>
> Isn't that the exact same thing as saying that t + d - d == t?

No, because the overflow handling isn't reversible. Using the semantics
from Pike or Postgres:

2022-03-31 + 1 month == 2022-04-30.
But 2022-04-30 - 1 month == 2022-03-30.

If "spill over" extra days (IIRC, PHP does that but I'd have to check)
2022-03-31 + 1 month == 2022-05-01
2022-05-01 - 1 month == 2022-04-01

So t + d - d is not always == t. (If you fix this special case you'll
break some more common cases).

But I think (but haven't yet proven) that for any pair of datetimes t0
and t1 there should always exist at least one delta d such that t0 + d
== t1.

2022-03-31 + 30 days = 2022-04-30
2022-03-30 + 1 month = 2022-04-30
2022-03-31 + 31 days == 2022-05-01
2022-03-31 + 1 month + 1 day == 2022-05-01
2022-03-31 + 2 months - 30 days == 2022-05-01

Not sure which of the last three should be the canonical one. I can
make an argument for each of them.

> Or are you saying that, when you subtract two timestamps, you can
> never get one of the odd exceptions that would cause problems? Because
> I'd believe that; the net result would be that u+(t-u) == t, but
> u+((t+d)-(u+d)) might not equal t. Putting it another way: Shift
> invariance should *normally* hold, but there may be some exceptions at
> month ends (basically rounding error when you add/subtract a month)
> and DST switches.

Yes.

> When the time comes, if you need a hand putting together a PEP, feel
> free to reach out to me.

Thanks.

hp

--
_ | Peter J. Holzer | Story must make more sense than reality.
|_|_) | |
| | | hjp@hjp.at | -- Charles Stross, "Creative writing
__/ | http://www.hjp.at/ | challenge!"

Attachments: signature.asc (application/pgp-signature)

devel / comp.lang.python / Re: Pre-Pre-PEP: The datetime.timedeltacal class

1
server_pubkey.txt

rocksolid light 0.9.81
clearnet tor