Almer S. Tigelaar
06 / 10 / 2011, 09:00
Calculating the number of days between two arbitrary dates is doable for humans and trivial on modern computers. However, calculating the number of working days: Mondays through Fridays, is more complicated. In this puzzle you are asked to devise an algorithm for doing this. It is something you can do on the back of a napkin, so you don’t need anything besides pen, paper and the rational part of your brain.
Problem:
Given two dates
where
, what is the number of workdays
between these two dates? Assume that only Saturdays and Sundays are not workdays: holidays can be ignored.
You may use the following definitions augmented with any standard mathematical functions, like
and
.
is a date
- Subscripts are used to indicate different dates:

yields the number of days between two dates. This is negative if
and zero if the dates are identical
gives the day of the week for the given date as a number (1 = Monday, 2 = Tuesday, …, 7 = Sunday)
gives the number of the week for the specified date (in the range 1 up to including 53)
is the set of numbers that represent working days (a subset of the domain of the weekday function)
Try to work out a solution first, then expand mine below.
More »
Solution:
There are really two cases to consider.
If both days are in the same week:
,
the solution might seem simple:
. This will work provided that both dates have a
less than or equal to five. If this is not the case, we need a more complex function:
. The
function returns the lesser of its two arguments (or either one in case they are equal). The +1 is to count the end date as a whole day. Note that we exploit here the fact that the workdays form a continuous range (1–5).
If both days are not in the same week:
,
then we must devise a way to find the number of weekends in between the two dates (each weekend subtracts two days from the interval
). We can do this in three steps:
- Determine if the starting day is in a workweek:
. If so, then set this as the initial count:
, otherwise set
.
now covers the number of working days in the first week of the range. To find the number of remaining days we first subtract
days from the days between the dates
. We wil define this as:
.
- The number of weekends must be
, since each weekend consists of two days, we must subtract this twice, giving:
. The
function is an integer division yielding a whole number. It is equivalent to
(the floor of a division, in this case between
and 7).
These steps are the full solution for the case where the weeks are not equal. Below are some examples of the method presented. However, perhaps you’ve come up with a simpler or more elegant solution? Let me know in the comments below.
Examples:
For the number of working days between
16-02-2009 (weekday 1) and
18-02-2009 (weekday 3): since these are within the same week (week 8), the number of working days is:

For the number of working days between
16-02-2009 (weekday 1) and
22-02-2009 (weekday 7): these are also within the same week (week 8), but the end date is in the weekend. Still this should work:

For the number of working days between
16-02-2009 (weekday 1) and
25-02-2009 (weekday 3): these are not within the same week, thus we must use the three step approach:



Here we see that the last part of the formula has no effect. This is always true for adjacent weeks, since
only if
.
So, now for non-adjacent weeks:
For the number of working days between
09-02-2009 (weekday 1) and
25-02-2009 (weekday 3):



More in Puzzles:
2 comments
add your commentThings become much easier if you're also allowed to subtract an integer from a date, resulting in a new date. Then you can just look at the number of days between the dates, div it by 7 to obtain whole weeks — for which you can count 5 working days –, and subtract these weeks from d2. You're left with a new d2 within a week of d1, and count the remaining working days by enumeration. See line 7-14 of http://pastebin.com/YNeCtDtz
Sander Eon 16 / 10 / 2011 wrote:
@Sander E I played around with your code, it's a nice solution that seems to work well for all the cases presented, and indeed simplifies the problem a lot as you pointed out. Thanks for sharing
almer.tigelaaron 19 / 10 / 2011 wrote: