Skip to content

Instantly share code, notes, and snippets.

@zenweasel
Created September 30, 2015 00:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zenweasel/41f97c6b5a4fb30e7119 to your computer and use it in GitHub Desktop.
Save zenweasel/41f97c6b5a4fb30e7119 to your computer and use it in GitHub Desktop.
TimeRange Object
#!/usr/bin/env python
# -*- coding: utf-8 -*-
class TimeRange(object):
"""
A basic structure to allow use to reason about non-contiguous dateranges in a single place
"""
def __init__(self, start_dt=None, end_dt=None, ranges=None):
self.start_dt = start_dt
self.end_dt = end_dt
if ranges is None:
self.ranges = [self]
else:
self.ranges = ranges
def format(self, dt):
return dt.time()
def add(self, new_range):
if getattr(new_range, 'start_dt') is None or getattr(new_range, 'end_dt') is None:
raise ValueError('Ranges must have a start and end dt')
if new_range.start_dt > self.end_dt or new_range.end_dt < self.start_dt:
# New range does not overlap with any existing ranges
self.ranges.append(new_range)
return
if new_range.start_dt < self.start_dt:
self.start_dt = new_range.start_dt
if new_range.end_dt > self.end_dt:
self.end_dt = new_range.end_dt
if new_range.start_dt > self.start_dt and new_range.end_dt < self.end_dt:
# if the new range is already within the existing range then ignore it. Then why is this
# here? Just to make sure it's clear we didn't forget about that case
pass
def subtract(self, new_range):
if new_range.start_dt > self.start_dt and new_range.end_dt < self.end_dt and len(self.ranges) == 1:
# If range is later than start and earlier then finish, split this range into two
# contiguous ranges
self.ranges[0] = (self.start_dt, new_range.start_dt)
self.ranges.append((new_range.start_dt, self.end_dt))
if new_range.start_dt < self.start_dt and new_range.end_dt < self.end_dt:
# if new range starts earlier and ends earlier than existing range then trucate range
# fo start at new ranges end time
self.start_dt = new_range.end_dt
if self.start_dt < new_range.start_dt < self.end_dt < new_range.end_dt:
self.start_dt = new_range.end_dt
def __repr__(self):
time_range_string = ''
for r in self.ranges:
time_range_string += '[{0} - {1}] '.format(self.format(r.start_dt), self.format(r.end_dt))
return time_range_string
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment