How to Calculate Working Days Between Dates Excluding Holidays
A project manager once asked me how many working days were left in a quarter for a contractor billing dispute. I counted on my fingers, got it wrong by three days, and learned the most important lesson in date arithmetic: never count working days by hand. Excel has a function for it, and it takes about thirty seconds once you know the setup.
The function: NETWORKDAYS
=NETWORKDAYS(start_date, end_date, [holidays])
NETWORKDAYS counts the weekdays (Monday to Friday) between two dates, inclusive of both endpoints, then subtracts any dates that appear in your holidays list. Weekends are always Saturday and Sunday; that part is not configurable. If you need different weekends, there is a variant below.
Worked example: September 2026
=NETWORKDAYS("2026-09-01","2026-09-30") returns 22.
September 2026 has 30 days. Subtract 8 weekend days (four Saturdays, four Sundays) and you get 22 working days. No holiday list needed for this month in the US, since Labor Day fell on September 7 and is already excluded as a Monday.
Wait, check that: September 7, 2026 is Labor Day, a Monday, so the raw weekday count of 23 drops to 22 when you pass the holiday list. Which brings us to the part everyone gets wrong.
Feed it a real holiday list
The third argument is a range or array of dates to exclude. Put your holidays in a column, say H5:H13, and reference it:
=NETWORKDAYS(B5, C5, $A$2:$A$5)
For a whole column of projects, copy the formula down with the holiday range locked. Two rules I enforce on every sheet:
- Store holidays as real dates, not text. NETWORKDAYS tolerates text that looks like a date, but it is unreliable. Use actual date values or the DATE() function. A #VALUE! error almost always means a text imposter in the holidays range.
- Weekend holidays are not double-counted. If Christmas falls on a Saturday and appears in your list, NETWORKDAYS does not subtract it twice. Safe to include observed-date duplicates only if your payroll policy actually observes them.
Where do you get the holiday list? A free public holidays CSV, like the one on this site, drops straight into the holidays column. Twenty-one countries, 2026 and 2027, no API key.
When weekends are not Saturday and Sunday: NETWORKDAYS.INTL
Middle Eastern workweeks, retail schedules, and shift operations need custom weekends:
=NETWORKDAYS.INTL(start_date, end_date, [weekend], [holidays])
The weekend argument is either a code or a 7-character string where 1 means non-working day, starting with Monday. "0000011" means the standard Saturday-Sunday weekend. "0000110" gives you Friday-Saturday weekends, the pattern used in several Gulf countries.
Three errors and what they mean
- Same start and end date, weekday, returns 1. Not 0. Both endpoints are inclusive. Same date on a Saturday returns 0.
- End date before start date returns a negative number. That is by design, and it is useful for overdue calculations.
- #NUM! from WORKDAY. The related WORKDAY function (which finds the date N working days out) throws #NUM! if the result lands on an invalid date or the weekend argument is malformed. Check the weekend code first.
The Google Sheets version
Identical syntax. =NETWORKDAYS(start, end, holidays) works in Sheets with the same inclusive-endpoint behavior, and NETWORKDAYS.INTL exists there too. Your holiday CSV imports as a date column the same way.
Download the free public holidays CSV. 21 countries, 2026-2027, no signup.
Download the holidays CSV
FAQs
Does NETWORKDAYS include the start and end dates?
Yes, both endpoints are inclusive. If the start and end are the same weekday, the result is 1. If that day is a weekend or a listed holiday, the result is 0.
Can NETWORKDAYS handle weekends other than Saturday and Sunday?
Not the plain version; its weekend is fixed. Use NETWORKDAYS.INTL, which accepts a weekend code or a 7-character string like "0000011" where 1 marks a non-working day, Monday first.
Why does my NETWORKDAYS formula return #VALUE!?
Almost always because a start date, end date, or one of the holiday entries is text rather than a real Excel date. Convert the range to date values and the error clears.