---
title: "What Is a Business Day? How to Calculate Business Days in Code"
url: https://apyhub.com/blog/what-is-a-business-day-how-to-calculate-business-days-in-code
author: ApyHub
published: 2026-09-18T14:06:20.28522Z
---

# What Is a Business Day? How to Calculate Business Days in Code

# What Is a Business Day? How to Calculate Business Days in Code

## Introduction

A business day is any day from Monday to Friday that is not a public holiday. Saturdays, Sundays and holidays do not count, so "5 business days" is usually a full calendar week, and longer when a holiday falls inside it.

That definition fits in one sentence and hides most of the bugs. If you have ever shipped a delivery estimate, an SLA timer, a payment date or a contract deadline, you have written business-day logic, and it was probably wrong on at least one day of the year. This guide walks through the naive implementation, the edge cases that break it, what the common libraries do and do not handle, and when to hand the problem to an API.

## The naive version, and where it breaks

Here is the function most of us write first:

```js
function addBusinessDays(date, days) {
  const d = new Date(date);
  while (days > 0) {
    d.setDate(d.getDate() + 1);
    const day = d.getDay();
    if (day !== 0 && day !== 6) days--;
  }
  return d;
}

addBusinessDays("2027-12-22", 3);
```

Ask it for 3 business days after Wednesday 22 December 2027 in the US. The correct answer is Tuesday 28 December, because Friday 24 December is the observed Christmas holiday. We ran the function in three time zones:

| Server time zone  | Result          | Correct?                                              |
| ----------------- | --------------- | ----------------------------------------------------- |
| UTC               | Mon 27 Dec 2027 | No, it counts the Christmas holiday as a business day |
| America/New\_York | Fri 24 Dec 2027 | No, it returns a holiday                              |
| Asia/Tokyo        | Mon 27 Dec 2027 | No                                                    |

Two separate bugs are hiding in ten lines. The function knows nothing about holidays. And `new Date("2027-12-22")` parses a date-only string as midnight UTC, which is still 21 December in New York, so the whole calculation starts a day early and lands on Christmas itself.

## The edge cases that break business-day logic

Most production bugs come from one of these seven.

### 1. Holidays observed on a different day

When a US federal holiday falls on a Saturday, it is observed on the Friday before. On a Sunday, it moves to the Monday after. In 2027 that moves Christmas to Friday 24 December and pulls New Year's Day 2028 back to Friday 31 December 2027, so a holiday dated in one year lands in the previous one. The UK, Canada and Australia move weekend holidays too. Germany and France do not. Hard-coding "25 December" gets all of these wrong. Our [2027 working days guide](https://apyhub.com/blog/how-many-working-days-are-in-2027-by-country-and-month) lists how each country handles it, with the full counts by month.

### 2. Which definition of "business day"

Even inside one country, the definition changes with the rule you are implementing. In US banking, Regulation CC lists specific holidays and states that when one falls on a Sunday, the following Monday is not a business day. It says nothing similar for Saturdays, so the Friday a federal office takes off can still be a business day for funds availability, as [NAFCU's compliance team explains](https://nafcu.org/node/35148). Other definitions ignore the calendar entirely and ask whether the institution is open for substantially all of its business. In Australia, the [PPSR's legal definition](https://www.ppsr.gov.au/business-day) also excludes every day between Christmas Day and New Year's Day. If your code implements a regulation or a contract, the definition in that document wins over any library default.

### 3. Regional calendars

"Germany" is not one holiday calendar. In 2027, Bavaria has three more weekday holidays than the nationwide list, and Berlin has one more. Scotland and England have different bank holidays, each Canadian province sets its own, and New South Wales added a one-off holiday for 26 April 2027. A single country code is often not specific enough.

### 4. Different weekends

Saturday and Sunday are not the weekend everywhere. Several countries, including Saudi Arabia and Israel, have a Friday and Saturday weekend. A `day !== 0 && day !== 6` check is a hard-coded assumption about your users' location.

### 5. Inclusive or exclusive ranges

Does "business days between 1 and 5 March" include 5 March? Different tools disagree. NumPy's `busday_count` excludes the end date, [per its documentation](https://numpy.org/devdocs/reference/generated/numpy.busday_count.html). Other tools count both ends. Pick one convention, document it, and write a test for it, because an off-by-one here changes every SLA you report.

### 6. Cutoff times

A support ticket opened at 17:55 on a Friday and one opened at 18:05 can have different deadlines if your SLA only starts counting within business hours. "Today" is a business day only until your cutoff. Model the cutoff explicitly instead of hoping the date rolls over at midnight.

### 7. Time zones

As the naive example showed, the server's time zone can move a date by one day before you even start counting. Store and calculate business dates as plain calendar dates in the time zone of the business that owns the deadline, not the server's.

## Libraries, and what they leave to you

Most languages have good tools for the weekend part. The holiday part is almost always your job.

### Python: NumPy

python

```python
import numpy as np

us_holidays_dec_2027 = ["2027-12-24", "2027-12-31"]

np.busday_offset("2027-12-22", 3, roll="forward", holidays=us_holidays_dec_2027)
# numpy.datetime64('2027-12-28')

np.busday_count("2027-12-01", "2028-01-01", holidays=us_holidays_dec_2027)
# 21  (end date excluded)

np.busday_count("2027-01-01", "2028-01-01", weekmask="Sun Mon Tue Wed Thu")
# 260  (Friday and Saturday weekend)
```

NumPy is fast and supports custom weekends through `weekmask`, but the `holidays` list is whatever you pass in.

### Python: pandas

python

```python
import pandas as pd
from pandas.tseries.holiday import USFederalHolidayCalendar
from pandas.tseries.offsets import CustomBusinessDay

us_business_day = CustomBusinessDay(calendar=USFederalHolidayCalendar())

pd.Timestamp("2027-12-22") + 3 * us_business_day
# Timestamp('2027-12-28 00:00:00')
```

pandas ships a US federal calendar that handles observed dates, including 31 December 2027. For any other country you define the rules yourself or pull in the `holidays` package, and you need to update it when governments change the list.

### JavaScript: date-fns

javascript

```js
import { addBusinessDays, differenceInBusinessDays } from "date-fns";

addBusinessDays(new Date(2027, 11, 22), 3);
// Mon Dec 27 2027 (Christmas observed is not skipped)
```

date-fns skips Saturdays and Sundays only. Its own [changelog](https://github.com/date-fns/date-fns/commit/da817a6896506631151e045c488d02c370930e24) notes that it does not avoid holidays that fall on a weekday. It is correct for weekends and wrong for any date range that contains a holiday.

### SQL: a calendar table

For reporting and batch jobs, a calendar table is the most reliable approach, because every query reads the same answer:

sql

```ts
CREATE TABLE calendar AS
SELECT d::date AS date,
       EXTRACT(ISODOW FROM d) < 6 AS is_business_day
FROM generate_series('2020-01-01'::date, '2035-12-31'::date, interval '1 day') AS d;

UPDATE calendar SET is_business_day = false
WHERE date IN (SELECT date FROM public_holidays WHERE country = 'US');

SELECT COUNT(*) FROM calendar
WHERE date >= '2027-12-01' AND date < '2028-01-01' AND is_business_day;
-- 21
```

The catch is the `public_holidays` table. Someone has to fill it for every country you support and keep it current.

## Using an API instead

Every approach above leaves the same job on your plate: maintaining holiday data for every country and region you serve, every year, forever. That is the part worth handing off.

The [Business Days Calculator API](https://apyhub.com/creightonnick0/service/business-day-math) does business-day math against maintained holiday calendars for the US, UK, Canada, Australia, Germany, France and India. One endpoint covers adding days, counting days, checking a single date and listing holidays:

bash

```bash
curl -X POST "https://api.eu.apyhub.com/creightonnick0/business-day-math" \
  -H "apy-token: $APY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"mode":"add","date":"2027-12-22","days":3,"country":"US"}'
```

json

```json
{
  "mode": "add",
  "input": "2027-12-22",
  "result": "2027-12-28",
  "country": "US",
  "business_days": 3,
  "result_weekday": "Tuesday",
  "holidays_skipped": [
    { "date": "2027-12-24", "name": "Christmas Day (observed)" }
  ]
}
```

The request takes a plain `YYYY-MM-DD` date, so there is no time zone to get wrong. `holidays_skipped` tells you exactly why a deadline moved, which makes the result easy to debug and easy to explain to a customer. Its `count` mode excludes the end date, the same convention as NumPy.

To count working days in a range with a breakdown of weekends and holidays, use the [Working Day Calculator API](https://apyhub.com/apyhub/service/count-working-days). Note that it counts both the start and end date:

bash

```bash
curl -X GET "https://api.eu.apyhub.com/apyhub/count-working-days?country=DE&start=2027-01-01&end=2027-12-31" \
  -H "apy-token: $APY_TOKEN"
```

json

```json
{
  "data": {
    "holidays": 5,
    "weekends": 104,
    "total_days": 365,
    "working_days": 256
  }
}
```

To show users the holiday dates themselves, the [Public Holidays API](https://apyhub.com/apyhub/service/public-holidays) returns them by country and year.

All three are available through [ApyHub MCP](https://apyhub.com/mcp), so AI agents can discover, evaluate and call them directly without a hand-written wrapper or tool definition. That matters more than it sounds: ask a language model what date is 10 business days from now and it will usually do the naive calculation in its head. An agent with a calendar-aware tool gets the real answer.

You can try each API in its playground. Start for free with 5 API calls a day, no card required.

[**Start for free →**](https://apyhub.com/)

## Choosing the right approach

| Approach               | Weekends             | Observed holidays                 | Regions               | Who maintains the holiday data |
| ---------------------- | -------------------- | --------------------------------- | --------------------- | ------------------------------ |
| Hand-written function  | Hard-coded           | No                                | No                    | You                            |
| date-fns               | Yes                  | No                                | No                    | You                            |
| NumPy                  | Yes, custom weekends | Only if you pass them             | Only if you pass them | You                            |
| pandas with a calendar | Yes                  | Yes, for the calendars you define | If you define them    | You                            |
| SQL calendar table     | Yes                  | If you load them                  | If you load them      | You                            |
| Business-day API       | Yes                  | Yes                               | Per supported country | The provider                   |

For a one-country internal tool, a library plus a holiday list you review once a year is fine. For anything customer-facing across several countries, the cost is in keeping the calendars right, not in the date arithmetic.

## Conclusion

A business day is Monday to Friday minus public holidays. Implementing that correctly means handling observed holidays, regional calendars, different weekends, inclusive or exclusive ranges, cutoff times and time zones. Libraries solve the weekend and arithmetic part well. None of them solve the ongoing work of keeping holiday data correct for every market you serve.

Decide your conventions, write tests for the dates that break things (31 December 2027 is a good one), and keep holiday data out of your codebase if you can. For the actual number of working days per country and month in 2027, see our guide to [how many working days are in 2027](https://apyhub.com/blog/how-many-working-days-are-in-2027-by-country-and-month).

[**Browse the ApyHub catalog →**](https://apyhub.com/catalog)

## FAQ

**What is a business day?** Any day from Monday to Friday that is not a public holiday. Some regulations and contracts define it more precisely, so check the definition that applies to you.

**Is Saturday a business day?** Usually not. Under US Regulation CC, Saturday is never a business day, even if a bank branch is open.

**Do holidays count as business days?** No. Public holidays that fall on a weekday are excluded, and in many countries a holiday that falls on a weekend moves to a nearby weekday that is also excluded.

**How long is 5 business days?** Usually 7 calendar days, for example Monday to the following Monday. If a holiday falls inside the range, add one day for each holiday.

**How do I add business days in JavaScript?** date-fns `addBusinessDays` skips weekends but not holidays. To skip holidays, check each date against a holiday list or call a business-day API.

**How do I exclude holidays in NumPy?** Pass them to the `holidays` argument of `busday_count` or `busday_offset` as `YYYY-MM-DD` strings or `datetime64` values.

**Should a business-day count include the end date?** There is no universal rule. NumPy excludes it, and some tools include it. Pick one convention, document it and test it.

**Why does my business-day calculation return the wrong day?** The most common causes are a missing observed holiday, a date parsed in the wrong time zone, or an off-by-one between inclusive and exclusive ranges.

**What are business days vs working days?** In most contexts they mean the same thing. "Business days" is common in banking, shipping and contracts. "Working days" is common in HR and payroll.

***

## About ApyHub

[ApyHub](https://apyhub.com/) is a curated API catalog and trusted operational layer. It gives developers and AI agents access to 450+ services and 1,500+ endpoints through a single subscription, with new APIs and providers onboarded continuously. Usage is billed in atoms, a unit that reflects the actual work of each call and is pooled across the entire catalog.

Every endpoint ships with machine-readable certification covering data residency, retention, sub-processors and alignment with GDPR, SOC 2 and ISO 27001, and is MCP-ready by default so agents can discover and call it without custom glue code.

ApyHub is headquartered in Amsterdam, with offices in the Netherlands, Greece and India. More than 65,000 developer workspaces use the catalog every month. There is a free tier and no card is required to start.

If you build APIs, you can publish yours to the catalog at [apyhub.com/become-a-provider](https://apyhub.com/become-a-provider).
