[Tutor] working with time spans ?

Tim Peters tim.one at comcast.net
Fri Jun 4 19:30:10 EDT 2004

```[Michele Alzetta]
> Thanks to Danny Yoo's suggestion I got to this, might be interesting:
>
> from time import mktime class TimeSpan(object):
>     def __init__(self, startimetuple, endtimetuple):
>         self.starttime = mktime(startimetuple)
>         self.endtime = mktime(endtimetuple)
>     def __contains__(self, timespan):
>          return (self.starttime <= timespan.starttime) and \
>                 (self.endtime >= timespan.endtime)
>
> periodstart = (2004, 6, 01, 8, 0, 0, 0, 0, 0)
> periodend = (2004, 7, 01, 8, 0, 0, 0, 0, 0)
> shiftperiod = TimeSpan(periodend,periodstart)

The order of the arguments is backwards there, isn't it?  That is, didn't
you want to pass periodstart first?  As written, nothing can actually be in
shiftperiod, and both tests below are False.

> shift1start = (2004, 6, 15, 8, 0, 0, 0, 0, 0)
> shift1end = (2004, 6, 15, 20, 0, 0, 0, 0, 0)
> shift1 = TimeSpan(shift1start,shift1end)
>
> shift2start = (2004, 7, 15, 8, 0, 0, 0, 0, 0)
> shift2end = (2004, 7, 15, 20, 0, 0, 0, 0, 0)
> shift2 = TimeSpan(shift2start,shift2end)
>
> shift1 in shiftperiod
> True
>
> shift2 in shiftperiod
> False
>
> which ought to come in pretty handy for my purposes.
>
> Actually all I'm interested in are years, months, days, hours and minutes
> so the tuples with 9 elements are a bit of a nuisance.
>
> Would it be a good idea to make TimeSpan inherit from time and change the
> mktime method for instance ?

You can't, because time is a module, and you can only inherit from classes
(a module isn't a class).

The better news is that there's really no need for the time module at all:
Python can compare tuples directly.

So this does the same thing (but where I swapped the order of arguments as
noted above):

class TimeSpan(object):
def __init__(self, startimetuple, endtimetuple):
self.starttime = startimetuple
self.endtime = endtimetuple

def __contains__(self, timespan):
return (self.starttime <= timespan.starttime and
self.endtime >= timespan.endtime)

periodstart = (2004, 6, 1, 8)
periodend = (2004, 7, 1, 8)
shiftperiod = TimeSpan(periodstart, periodend)

shift1start = (2004, 6, 15, 8)
shift1end = (2004, 6, 15, 20)
shift1 = TimeSpan(shift1start, shift1end)

shift2start = (2004, 7, 15, 8)
shift2end = (2004, 7, 15, 20)
shift2 = TimeSpan(shift2start, shift2end)

print shift1 in shiftperiod
print shift2 in shiftperiod

That prints True, then False.

You'll eventually want to think about using the datetime module.  Doing so
will check that the dates passed in are sane, and provide a strong base to
build fancier stuff on.  For example, just replace the first 4 lines above
with:

from datetime import datetime

class TimeSpan(object):
def __init__(self, startimetuple, endtimetuple):
self.starttime = datetime(*startimetuple)
self.endtime = datetime(*endtimetuple)

Everything else works the same then, and not even the __contains__ method
needs to change.  You can easily add other interesting methods to your

def length(self):
return self.endtime - self.starttime

and then

print shiftperiod.length()
print shift1.length()
print shift2.length()

prints

30 days, 0:00:00
12:00:00
12:00:00

It's best to get a new job before you have to worry about daylight saving
time, though <wink>.

```