[Python-ideas] Please reconsider the Boolean evaluation of midnight

Tim Peters tim.peters at gmail.com
Fri Mar 7 02:19:28 CET 2014


[Tim]
>> The only difference between time and timedelta is in implementation
>> details.

[Greg]
> Only if you define it that way.

Sorry, don't know what you mean there.  But then I don't draw much
distinction between "defining" something and "implementation details".
 `time` and `timedelta` objects are both exact values with microsecond
resolution; the operations each supports is a matter of definition +
implementation.

> To my way of thinking, a time-of-day is like a mod-24-hour datetime,
> not a mod-24-hour timedelta.

Heh.  I'll ponder that and see if I can make sense of it tomorrow ;-)

> It seems you're thinking of it as a mod-24-hour timedelta.

No.  I'm saying: (1) it _can_ be thought of that way; and, (2) while
that's not how `time` was initially released, there was some effort
not to _preclude_ later extensions viewing it that way.

As is, the datetime module offers no obvious solution to problems like
"the clock reads 6:43 now; what will it read 57 minutes from now?".
`time` objects support no arithmetic of any kind.  The world wouldn't
really collapse if time(6, 43) + time(minute=57), or if time(6, 43) +
timedelta(minutes=57), didn't blow up but returned the obvious result
as a time object.

> Given that, I can see why you think that it's bizarre
> to attach a timezone to one. In fact, I'd say if that's
> really how a time object is meant to be interpreted,
> they shouldn't even be *allowed* to have a timezone,
> any more than a timedelta can.

No, it's bizarre to attach a timezone to a time object because most
tzinfo subclasses don't - and can't - know what to return for the UTC
offset in the absence of - at least - month and day info too.  Hour,
minute, second and microsecond aren't usually enough to determine
whether "daylight time" is in effect, and most tzinfo subclasses do
attempt to model daylight time.  And because daylight time is a
political conceit, most tzinfo subclasses also need year info.  That
has nothing to do with whether times are viewed abstractly,
concretely, etc - it has to do with that time zones generally aren't
_defined_ in terms of isolated time-of-day info.  It's 7:13 PM in US
Central.  Is that daylight (CDT) or standard (CST) time?  It's
impossible to answer.  What's the corresponding UTC time?  Ditto.

While time objects don't support arithmetic they do support all
comparison operators.  And this is another case where the docs explain
_how_ comparison of aware time objects works, but a close reading
reveals that the result generally makes no sense.  In effect, the time
objects are converted to UTC before comparison, but correct conversion
to UTC is generally impossible without month, day and year info too.

A user intimately familiar with how all this works can define tzinfo
subclasses that make time object conversions with the kinds of errors
they prefer. but that too is ... bizarre.

> In any case, I don't see how this interpretation
> justifies the truthiness behaviour with timezones.
> From my reading of the docs, the *intention* seems
> to be for midnight UTC to be false and all other
> times to be true. I would never have suspected the
> actual behaviour with negative offsets, which looks
> like an outright bug to me. Or is there some reason
> for it that I'm not seeing?

Truthiness would become useful if time() (i.e., the naive time object
with all 0 fields) acted as an additive identity in some extension
that allowed time object addition.  That's all.  I put more thought
into writing that sentence than into what truthiness of aware time
objects returned - and I bet it shows ;-)

If more thought had gone into it, and assuming it remained the case
that time objects had to support tzinfo members (despite that doing so
makes little sense), and assuming it remained the case that we wanted
to keep the _possibility_ of later time arithmetic open, I'd amend the
truthiness rules to that False was equivalent to that

    the naive time converted to minutes
    minus
    the UTC offset (or 0 if tzinfo=None)

is 0 mod 24*60.  Which would be a long way of saying "midnight UTC",
but a better way because: (1) again, it's not usually possible to do
_correct_ conversion of a time object to UTC; and, (2) it's not
"midnight" that's important to an additive identity, it's "0".


More information about the Python-ideas mailing list