Created
December 6, 2012 14:18
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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