[DB-SIG] ODMG Date/time classes
Jeffrey C. Jacobs
timehorse@unforgettable.com
Thu, 18 Dec 1997 12:25:48 -0500
-----Original Message-----
From: Magnus Lycka [SMTP:magnus.lycka@tripnet.se]
Sent: Thursday, December 18, 1997 4:18 AM
To: Jim Fulton; db-sig@python.org
Subject: Re: [DB-SIG] ODMG Date/time classes
At 16:20 1997-12-17 -0500, Jim Fulton wrote:
> def __mul__(self, anInt):
> """Multiply an interval by an integer"""
>
> __rmul__=3D__mul__
>
> def __div__(self, anInt):
> """Divide an interval by an integer"""
Why not allow floats? I assume you've just copied the standard,
but what would be the reason for not allowing mult and div with
floats? Seconds is float, so division should handle a floating
point result anyway. It seems like an arbitrary restriction.=20
I'm not quite sure what integer divition and remainder would
mean for a time interval. If it had just been defined as days
I would get it, but since it is defined to fractions of seconds...
I think mod and divmod mistakes. They really only make sense when both
nominator and denominator are integers. They don't make sense when the
interval is a compound where it's unclear what the unit is.
Somehow, it seems that if t =3D 5 days, then t div 2 =3D 2 and t rem 2 =
=3D 1,
but t =3D 5 days =3D 120 hours =3D> t div 2 =3D 60 hours (=3D 2=BD =
days), t mod 2 =3D 0!!!=20
[The TimeHorse] IMHO, I see this as an issue of units. Imagine we talk
just about seconds for a moment. Remember "1 sec" is not the same as =
"1".
"1 sec" + "1" is "1 sec + 1", not "2 sec". What I'm getting at is, from =
a
scientific POV, "sec", "min", "day", etc are all conversion factors. In =
a
way, you can think of them as variable unknowns. In effect, when we say
"1 sec", we in a sense mean "1 * sec". Thus, to combine terms, seconds
can only be added or subtracted to seconds, and so on. Of course, since
there are conversion factors, such as "1 min =3D 60 sec" =3D> "(1 min) / =
(60
sec) =3D 1", and any number times 1 is equal to itself, we have
"120 sec" =3D>
"(120 sec) * 1" =3D>
"120 sec * ((1 min) / (60 sec))" =3D>
"(1 min) * ((120 sec) / (60 sec))" =3D>
"(1 min) * (120 / 60)" =3D>
"2 min"
Thus, "1 min + 120 sec" does make sense, and is "3 min". Yeah, yeah! I
know this is stuff we all learned in High School, but I just wanted to =
set
up for the basis of my thoughts.
Anyway, extending this logic to multiplication, obviously units can
cancel. Thus, "(120 sec) / (60 sec)" =3D> "2", since the "sec" cancels.
Thus, when you divide a TimeSpan by a TimeSpan, you produce a clearly-
defined number. There are exactly 2 "60 sec" in "120 sec". Equally, =
when
you multiply back, "2 * 60 sec =3D 120 sec", producing a TimeSpan from a
TimeSpan. However, "1 sec * 1 sec =3D 1 sec^2", which is really beyond =
the
scope of what we want to support with DateTime, and thus should be
disallowed. Equally, "2 / (1 sec) =3D 2 sec^-1" makes as little sense =
as "1
sec^2", and thus should also be disallowed. However, "120 sec / 2 =3D =
60
sec" is just as valid as "(120 sec) / (60 sec) =3D 2". Thus, so far:
Parameter ----------------Produces---------------
__mul__ __rmul__ __div__ __rdiv__
TimeSpan Exception Exception Number Number
Number TimeSpan TimeSpan TimeSpan Exception
Of course, I am only talking about TimeSpans here; multiplication and
divisions by an Absolute Date really don't make much sense, since they =
do
not take into account the Epoch. For the Modulo operation, we have the
definition:
a / b =3D c; a % b =3D d =3D>
a - d =3D b * c.
Thus d, the result of the Modulo, must always be of the same type as a.
Since we can not subtract a Number from a TimeSpan, if a, the left-hand
Side of the Modulo, is a TimeSpan, then d, the result of the modulo must
be so as well, irregardless of the type of b. However, as I mentioned
above, a may not be a Number if b is a TimeSpan because then c becomes
invalid. Thus, finally we have:
Parameter --------------------------Produces-------------------------
__mul__ __rmul__ __div__ __rdiv__ __mod__ __rmod__
TimeSpan Exception Exception Number Number TimeSpan TimeSpan
Number TimeSpan TimeSpan TimeSpan Exception TimeSpan Exception
Specifically,
"(130 sec) % (1 min)" =3D>
"(130 sec) % 60" =3D>
"10 sec".
Anyway, that's my opinion as to how the multiply-order operations
should work. As for Number, I agree that Floats, Ints as well as Longs
should be allowed, as long as we are consistent. The only problem I see
with what Number type to use is for TimeSpan / TimeSpan, which will
produce a Number of an unknown type. Certainly, in this case, a float
would be useful for its support of decimals, but a Long is allows =
infinite
precision of integers, so I guess the best result would depend on the
context.
Again, sorry that so much of this is common-knowledge. I just couldn't
resist codifying it here to make things easier.
Be Seeing You,
Jeffrey.
---
~,-;` The TimeHorse
Sometimes also a Dragon. . .
_______________
DB-SIG - SIG on Tabular Databases in Python
send messages to: db-sig@python.org
administrivia to: db-sig-request@python.org
_______________