Wednesday, August 06, 2014

Calculating the number of working days using Python

At times, we have a requirement to calculate the number of weekdays / working days between two dates.
Here's how you do it using Python:

from datetime import date, timedelta
start_date = date(2014, 07, 07)
end_date = date(2014, 07, 23)
all_days = [start_date + timedelta(days=x) for x in range((end_date-start_date).days + 1)]
working_days = sum(1 for d in all_days if d.weekday() < 5)
But the above method involves usage of loops.
A more optimized way of doing it would be:

from datetime import date, timedelta
start_date = date(2014, 07, 07)
end_date = date(2014, 07, 23)
# Calculate number of days in starting and ending week
start_week_days = min(start_date.weekday(), 4) + 1
end_week_days = min(end_date.weekday(), 4) + 1
# Calculate number of weeks between the dates
no_of_weeks = end_date.isocalendar()[1] - start_date.isocalendar()[1]
working_days = (5 * no_of_weeks) + end_week_days - start_week_days
# include the starting day if it is weekday
if start_date.weekday() < 5:
working_days += 1
view raw workingDays.py hosted with ❤ by GitHub
In our project, we faced a requirement where given a start date, we had to calculate end date as start date + x working days.
Using the above logic, we can do:

from datetime import date, timedelta
def calculate_end_date(start_date):
x = 45
working_days = 0
end_date = start_date + timedelta(days=x)
while working_days < x:
# Calculate number of days in starting and ending week
start_week_days = min(start_date.weekday(), 4) + 1
end_week_days = min(end_date.weekday(), 4) + 1
# Calculate number of weeks between the dates
no_of_weeks = ((end_date - datetime.timedelta(days=end_date.weekday()))
- (start_date - datetime.timedelta(days=start_date.weekday()))).days / 7
working_days = (5 * no_of_weeks) + end_week_days - start_week_days
# include the starting day if it is weekday
if start_date.weekday() < 5:
working_days += 1
# adjust the end date
end_date = end_date + timedelta(days = x - working_days)
return end_date
If you have a list of holidays to exclude, you could then do:

from datetime import date, timedelta
def calculate_end_date(start_date):
x = 45
working_days = 0
end_date = start_date + timedelta(days=x)
while working_days < x:
# Calculate number of days in starting and ending week
start_week_days = min(start_date.weekday(), 4) + 1
end_week_days = min(end_date.weekday(), 4) + 1
# Calculate number of weeks between the dates
no_of_weeks = ((end_date - datetime.timedelta(days=end_date.weekday()))
- (start_date - datetime.timedelta(days=start_date.weekday()))).days / 7
working_days = (5 * no_of_weeks) + end_week_days - start_week_days
# include the starting day if it is weekday
if start_date.weekday() < 5:
working_days += 1
# adjust the end date
end_date = end_date + timedelta(days = x - working_days)
# Create your own list of holidays
holidays = [date(2014, 01, 01), date(2014, 12, 25)]
for day in holidays:
if day >= start_date and day <= end_date:
# Check if end date is Friday, then skip the weekend
if end_date.weekday() == 4:
end_date = end_date + timedelta(days=3)
else:
end_date = end_date + timedelta(days=1)
return end_date

0 comments:

Post a Comment