[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
_______________