YADTR (Yet Another DateTime Rant)

M

Mark Lawrence

"I had a dangling pointer error, and blew my stack to half past last
wednesday"

IIRC the Germans (possibly amongst others) would say that as half to
last thursday, or is that thurstag? :)
 
J

Johannes Bauer

py> divmod(30, 24)
(1, 6)

That makes perfect intuitive sense: 30 hours is 1 day with 6 hours
remaining. In human-speak, we'll say that regardless of whether the
timedelta is positive or negative: we'll say "1 day and 6 hours from now"
or "1 day and 6 hours ago". But when we specify the sign:

py> divmod(-30, 24)
(-2, 18)

If an event happened 30 hours ago, it is correct to say that it occurred
"18 hours after 2 days ago", but who talks that way?

Well, no matter how timedeltas internal representation is and if they
use modular division or (they probably do, I agree) this shouldn't
affect the display at all. Internally they can use any arbitrary
representation, but for the external representation I think a very sane
requirement should be that for a given timedelta t with t > 0 it is its
string representation str(t) would satisfy:

"-" + str(t) == str(-t)

Besides, there's an infinite amount of (braindead) timedelta string
representations. For your -30 hours, it is perfectly legal to say

123 days, -2982 hours

Yet Python doesn't (but chooses an equally braindead representation).

Where can I enter a PIP that proposes that all timedelta strings are
fixed at 123 days (for positive, non-prime amount of seconds) and fixed
at -234 days (for all negative or positive prime amount of seconds)?

Cheers,
Johannes

--
Zumindest nicht öffentlich!
Ah, der neueste und bis heute genialste Streich unsere großen
Kosmologen: Die Geheim-Vorhersage.
- Karl Kaos über Rüdiger Thomas in dsa <[email protected]>
 
C

Chris Angelico

Besides, there's an infinite amount of (braindead) timedelta string
representations. For your -30 hours, it is perfectly legal to say

123 days, -2982 hours

Yet Python doesn't (but chooses an equally braindead representation).

It's not "equally braindead", it follows a simple and logical rule:
Only the day portion is negative. That might not be perfectly suited
to all situations, but it does mean that adding and subtracting whole
days will never change the representation of the time. That's a
reasonable promise. What you propose is completely arbitrary, and yes
it WOULD be braindead to have str() return that (although of course
this should be accepted as input).
Where can I enter a PIP that proposes that all timedelta strings are
fixed at 123 days (for positive, non-prime amount of seconds) and fixed
at -234 days (for all negative or positive prime amount of seconds)?

Doesn't need a PEP. Just subclass it or monkey-patch it and use it as
you will. :)

ChrisA
 
J

Johannes Bauer

It's not "equally braindead", it follows a simple and logical rule:
Only the day portion is negative. That might not be perfectly suited
to all situations, but it does mean that adding and subtracting whole
days will never change the representation of the time. That's a
reasonable promise.

Why would the stability of the *string* output of the time
representation be of any interest whatsoever? Do you have any even
halfways reasonable usecase for that?
What you propose is completely arbitrary,

No. What I propose is that for t > 0 this holds:

"-" + str(t) == str(-t)

Which is far from arbitrary. It follows "natural" rules of inverting
something (-abs(x) == -x), and it yields a (truly) human-readable form
of showing a timedelta.

Please don't mix this up with the very apparent braindead proposal of
mine. In case you didn't notice, this was irony at work. The word
"braindead" I chose to describe the format should have tipped you off to
that.
Doesn't need a PEP. Just subclass it or monkey-patch it and use it as
you will. :)

Nonono, you misunderstand: I want everyone to suffer under the braindead
representation, just as it is now!

Cheers,
Johannes

--
Zumindest nicht öffentlich!
Ah, der neueste und bis heute genialste Streich unsere großen
Kosmologen: Die Geheim-Vorhersage.
- Karl Kaos über Rüdiger Thomas in dsa <[email protected]>
 
J

Johannes Bauer

It's not "equally braindead", it follows a simple and logical rule:
Only the day portion is negative.

The more I think about it, the sillier this rule seems to me.

A timedelta is a *whole* object. Either the whole delta is negative or
it is not. It doesn't make sense to split it up in two parts and
arbitrarily define one to be always nonnegative and the other to have no
restrictions.

The only locical reasoning behind this could be to argue that "-2 days"
makes more sense than "-15 minutes". Which it doesn't.

Worse: Negating a timedelta (which I would argue is a fairly common
operation) makes the whole thing unstable representation-wise:
'-3 days, 23:59:30'

And it makes it extremely error-prone to the reader:
'-1 day, 23:59:59'

This looks MUCH more like "almost two days ago" than

'-00:00:01'

does.

In any case, the str() function is *only* about the representation that
can be read by humans. Therefore its highest priority should be to
output something that can, in fact, be easily parsed by humans. The
current format is nothing of the sort.

Cheers,
Johannes

--
Zumindest nicht öffentlich!
Ah, der neueste und bis heute genialste Streich unsere großen
Kosmologen: Die Geheim-Vorhersage.
- Karl Kaos über Rüdiger Thomas in dsa <[email protected]>
 
C

Chris Angelico

Why would the stability of the *string* output of the time
representation be of any interest whatsoever? Do you have any even
halfways reasonable usecase for that?


No. What I propose is that for t > 0 this holds:

"-" + str(t) == str(-t)

Which is far from arbitrary.

When you said "equally braindead", I took that as indicating that the
current representation is as braindead as "123 days, -2982 hours". My
point is that it's not as arbitrary as that. Your "real proposal", if
you like, is arguably better; but I'm just saying that the current one
isn't arbitrary.
It follows "natural" rules of inverting
something (-abs(x) == -x), and it yields a (truly) human-readable form
of showing a timedelta.

Please don't mix this up with the very apparent braindead proposal of
mine. In case you didn't notice, this was irony at work. The word
"braindead" I chose to describe the format should have tipped you off to
that.

Yes, I knew that that was irony. I was taking argument with your
declaration that the current form is just as bad. Taking it to a
different type: The repr() of a string tries to be short, where
possible, by using either single or double quotes, but won't use a raw
representation, nor triple-quoted:
' \\\\\\\\\\\\\\\\\\\\\\\\\\\\ '

You could argue that representing a string as raw or triple-quoted
would be "more correct", and yet the current repr is not arbitrary.
The current form is not actively bad, even if it would be possible to
find something better.
Nonono, you misunderstand: I want everyone to suffer under the braindead
representation, just as it is now!

Oh, absolutely! In that case, just slip a patch into the next point
release; people won't mind that changing in 3.4.1!

ChrisA
 
C

Chris Angelico

And it makes it extremely error-prone to the reader:

'-1 day, 23:59:59'

This looks MUCH more like "almost two days ago" than

'-00:00:01'

does.

It's easy when the timedelta is >-1 day. Is it as clear when it's
further negative?

In any case... what I'd suggest would be opening a tracker issue, or
discussing this on python-ideas, and seeing what core devs think of
the matter. I think that, on balance, it's probably better to show the
whole thing with the same sign; but should it be:
'-1 day, 00:00:01'

or should the hyphen be repeated:
'-1 day, -00:00:01'

? How does it read in a larger expression? All this bikeshedding, and
more, available gratis on python-ideas. :)

ChrisA
 
S

Skip Montanaro

I took a moment to scan the datetime documentation. The behavior of
str() on timedelta objects is very consistent, and matches the
internal representation. From the docs:

str(t) Returns a string in the form [D day, ][H]H:MM:SS[.UUUUUU],
where D is negative for negative t. (5)

Note (5) reads: String representations of timedelta objects are
normalized similarly to their internal representation. This leads to
somewhat unusual results for negative timedeltas.

Feel free to submit a patch to improve str(t), where t is negative,
though as Chris suggested, hashing this out on python-ideas would be a
good idea. I suggest you start with some concrete examples. There are,
as I see it, two common cases where t is negative:

-1 day < t < 0

and

t <= -1 day

Skip
 
C

Chris Angelico

There are,
as I see it, two common cases where t is negative:

-1 day < t < 0

and

t <= -1 day

There are two types of negative numbers: Those closer to zero than -1,
and those not closer to zero than -1. Yeah, I think those are the most
common cases. :)

ChrisA
 
R

Roy Smith

It's not "equally braindead", it follows a simple and logical rule:
Only the day portion is negative.

Simple and logical, yes. But also entirely braindead.
That might not be perfectly suited to all situations

Give ma a real-life situation where you would want such behavior.
What you propose is completely arbitrary, and yes
it WOULD be braindead to have str() return that

Chris, I believe you need to have your sarcasm detection circuitry
recalibrated :)
 
S

Skip Montanaro

There are,
There are two types of negative numbers: Those closer to zero than -1,
and those not closer to zero than -1. Yeah, I think those are the most
common cases. :)

Sorry I wasn't clear. I see two cases w.r.t. *display*, those where
you need to display the number of days back (possibly accounting for
even larger time intervals to make it more human readable), those
where you don't. Yes, as you observed, they completely cover the
negative timedelta space with two non-overlapping intervals.

Roy's original rant was about how a negative timedelta was
stringified, when what he seemed to care about was mostly the time
interval between now and the previous sunset (which will be less than
a day, unless your day length is advancing -- between the winter and
summer solstices -- and you compute that interval a few seconds before
sunset). The common "how long ago was sunset?" (|delta| < 1 day) case
is handled just fine by my little negate-the-timedelta hack, e.g.:
'-17:12:25.234000'

Negative timedeltas with a magnitude of one day or more require
something else, perhaps like the ISO8601 duration stuff (which I
personally find distasteful, but that might be the best you can do in
the absence of an anchor datetime).

Skip
 
A

Antoon Pardon

Simple and logical, yes. But also entirely braindead.

That you don't have a use for it and don't like it doesn't
make it brain dead.

Give ma a real-life situation where you would want such behavior.

What good would that do? The fact that someone else could
give a real-life situation where they wanted that, wouldn't
mean that you would recognize it as a situation where you
wanted it, and so you could still call it brain dead.

I don't recall specifics, but I do remember multiple times
where I was working with a structure that consisted of
a whole part and a fracture part where I found it useful
to have the fracture part always positive and displayed
as such.

Your background is obviously different and you don't like it.
Fine, that doesn't make it brain dead.
 
C

Chris Angelico

I don't recall specifics, but I do remember multiple times
where I was working with a structure that consisted of
a whole part and a fracture part where I found it useful
to have the fracture part always positive and displayed
as such.

One has already been shared in this thread: Logarithms, where the part
before the decimal is the scale and the part after the decimal is the
mantissa. Makes very good sense to negate the first without changing
the second.

ChrisA
 
T

Terry Reedy

In any case... what I'd suggest would be opening a tracker issue, or
discussing this on python-ideas, and seeing what core devs think of
the matter. I think that, on balance, it's probably better to show the
whole thing with the same sign; but should it be:

Before doing so, I suggest looking for the design discussion either on
the tracker or in python-ideas or py-dev lists.

'-1 day, 00:00:01'

or should the hyphen be repeated:

'-1 day, -00:00:01'

'-(1 day, 00:00:01)' should be unambiguous.
 
S

Steven D'Aprano

Simple and logical, yes. But also entirely braindead.

Do you think it is "braindead" for __str__ to return something which
follows the internal representation of the object?

Note that I'm not asking if that is the best choice for every object, or
even the best choice for any object. You've made an extremely strong
claim, by calling something "braindead" you're essentially arguing that
this is an *utterly irredeemable choice whatsoever* with absolutely no
redeeming features.

Hyperbole is fun, that's why we do it. It allows us to build up a nice
feeling of righteous indignation over something utterly outrageous and
indefensible, without having to worry about inconvenient distractions
like other points of view :)

Give ma a real-life situation where you would want such behavior.

Easy -- I'm debugging timedelta routines, and I want to easily see that
the timedeltas calculated match what I expect them to be when I print
them. The quickest, easiest and simplest way is for str(timedelta) to
follow the internal representation.

Oh look, that's exactly what the docs say:

"String representations of timedelta objects are normalized similarly to
their internal representation. This leads to somewhat unusual results for
negative timedeltas."

as Skip has already pointed out.

Is this the *best* choice for a timedelta? Probably not. But it's a
simple, logical, *reasonable* choice. It only fails the "reasonable" test
if you insist that timedelta objects *must* match the time-keeping
conventions of native English speakers, and any other convention is
unspeakable. For all we know, maybe (say) Koreans or Egyptians or Gaelic
Scots do say something like "It was a day ago, less four hours" meaning
twenty hours ago. Stranger things happen in natural language, and we
ought to be cautious about insisting that English conventions are
universal.

(Given Johannes Bauer's reaction, we can be fairly certain that German
speakers follow a similar convention to English speakers. Which shouldn't
be terribly surprising, since English is a Germanic language.)


A few seconds searching the bug tracker shows that this is not, in fact,
a bug in timedelta but probably a deliberate feature:

http://bugs.python.org/issue9430

This one is also relevant: http://bugs.python.org/issue1569623


Alas, the discussion appears to have been on #python-dev, which
(probably) means it is not archived anywhere.
 
E

Ethan Furman

Before doing so, I suggest looking for the design discussion either on the tracker or in python-ideas or py-dev lists.


'-(1 day, 00:00:01)' should be unambiguous.

Or change the comma to an and:

'-1 day and 00:00:01'
 
R

Roy Smith

Steven D'Aprano said:
Do you think it is "braindead" for __str__ to return something which
follows the internal representation of the object?

Yes. The whole idea of OOD is to decouple internal representation from
external behavior.
Easy -- I'm debugging timedelta routines, and I want to easily see that
the timedeltas calculated match what I expect them to be when I print
them. The quickest, easiest and simplest way is for str(timedelta) to
follow the internal representation.

That's what __repr__() is for.
Oh look, that's exactly what the docs say:

"String representations of timedelta objects are normalized similarly to
their internal representation. This leads to somewhat unusual results for
negative timedeltas."

Yes, I know that's what the docs say. That's why it's not an
implementation bug. It's a design bug :)
 
T

Terry Reedy

Before doing so, I suggest looking for the design discussion either on
the tracker or in python-ideas or py-dev lists.

And skip the troll word 'braindead'.

Terry Jan Reedy
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,077
Messages
2,570,566
Members
47,202
Latest member
misc.

Latest Threads

Top