Skip to content

Instantly share code, notes, and snippets.

@equinoxel
Created December 6, 2012 14:18
Show Gist options
  • Save equinoxel/4224749 to your computer and use it in GitHub Desktop.
Save equinoxel/4224749 to your computer and use it in GitHub Desktop.
A script to calculate total time from a set of (start. end) tuples
buf = """
15/10/1997 15/10/2001
03/03/1997 30/06/2000
01/10/1996 30/06/1997
15/11/2011 14/10/2012
15/11/2008 14/11/2011
10/10/2007 10/11/2008
01/12/2005 01/10/2007
01/11/2001 01/11/2005
"""
import datetime
import time
def intersect(periods):
"""
Perform iterative interval intersection from the input list of intervals.
"""
result = []
last_period = None
for period in periods:
if not last_period:
last_period = period
else:
if last_period['end'] < period['start']:
result.append(last_period)
last_period = period
else:
if last_period['end'] < period['end']:
last_period['end'] = period['end']
else:
print "period included"
result.append(last_period)
return result
def summum(periods):
"""
Calculate the sum (in years, months, days) from a list of periods.
Note that it does carry over if e.g. the number of months exceeds 12
when summing up.
"""
result = {'years': 0, 'months':0, 'days':0}
for period in periods:
e = period['end']
s = period['start']
years = e.year - s.year
months = e.month - s.month
days = e.day - s.day
# Get the days to be positive by substracting months
#
while days < 0:
days += 30
months -= 1
# Get the years to be positive by substracting years
#
while months < 0:
months += 12
years -= 1
result['years'] += years
result['months'] += months
result['days'] += days
while result['days'] > 30:
result['months'] += 1
result['days'] -= 30
while result['months'] > 12:
result['years'] += 1
result['months'] -= 12
return result
def main():
lines = [val.strip() for val in buf.split('\n')]
periods = []
# Load the lines in datetime.date objects.
#
for l in lines:
if not l:
continue
start, end = l.split()
print "Parsing:", start, end
start = time.strptime(start,"%d/%m/%Y")
end = time.strptime(end,"%d/%m/%Y")
start = datetime.date(start.tm_year, start.tm_mon, start.tm_mday)
end = datetime.date(end.tm_year, end.tm_mon, end.tm_mday)
periods.append({'start': start, 'end': end})
# Sort the time intervals based on their start values
#
periods = sorted(periods, key=lambda period: period['start'])
# Calcualte intersections
#
new_periods = intersect(periods)
# Print the result
#
print summum(new_periods)
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment