1.1 --- a/imiptools/period.py Tue Jan 13 22:39:53 2015 +0100
1.2 +++ b/imiptools/period.py Tue Jan 13 22:41:18 2015 +0100
1.3 @@ -20,6 +20,7 @@
1.4 """
1.5
1.6 from bisect import bisect_left, insort_left
1.7 +from imiptools.dates import get_datetime, get_start_of_day, to_timezone
1.8
1.9 # Time management.
1.10
1.11 @@ -104,6 +105,9 @@
1.12 """
1.13 Return an ordered time scale from the given list 'l' of tuples, with the
1.14 first two elements of each tuple being start and end times.
1.15 +
1.16 + The returned scale is a collection of (time, (starting, ending)) tuples,
1.17 + where starting and ending are collections of tuples from 'l'.
1.18 """
1.19
1.20 scale = {}
1.21 @@ -163,6 +167,46 @@
1.22
1.23 return slots
1.24
1.25 +def partition_slots(slots, tzid):
1.26 +
1.27 + """
1.28 + Partition the given 'slots' into separate collections having a date-level
1.29 + resolution, using the given 'tzid' to make sure that the day boundaries are
1.30 + defined according to the chosen time zone.
1.31 +
1.32 + Return a collection of (date, slots) tuples.
1.33 + """
1.34 +
1.35 + partitioned = {}
1.36 + current = None
1.37 + current_date = None
1.38 + previously_active = None
1.39 +
1.40 + for point, active in slots:
1.41 + dt = to_timezone(get_datetime(point), tzid)
1.42 + start_of_day = get_start_of_day(dt)
1.43 + this_date = dt.date()
1.44 +
1.45 + # For each new day, create a partition of the original collection.
1.46 +
1.47 + if this_date != current_date:
1.48 + current_date = this_date
1.49 + partitioned[current_date] = current = []
1.50 +
1.51 + # Add any continuing periods.
1.52 +
1.53 + if dt != start_of_day and previously_active:
1.54 + current.append((start_of_day, previously_active))
1.55 +
1.56 + # Add the currently active periods at this point in time.
1.57 +
1.58 + current.append((point, active))
1.59 + previously_active = active
1.60 +
1.61 + partitioned = partitioned.items()
1.62 + partitioned.sort()
1.63 + return partitioned
1.64 +
1.65 def get_spans(slots):
1.66
1.67 "Inspect the given 'slots', returning a mapping of event uids to spans."
1.68 @@ -174,8 +218,14 @@
1.69 for t in active:
1.70 if t:
1.71 start, end, uid = t[:3]
1.72 - start_slot = points.index(start)
1.73 - end_slot = points.index(end)
1.74 + try:
1.75 + start_slot = points.index(start)
1.76 + except ValueError:
1.77 + start_slot = 0
1.78 + try:
1.79 + end_slot = points.index(end)
1.80 + except ValueError:
1.81 + end_slot = len(slots)
1.82 spans[uid] = end_slot - start_slot
1.83
1.84 return spans