Calculating Business Days in JavaScript — Skip the Calendar Math
Every developer eventually has to answer a question like: "How many business days until the deadline?" or "What date is 10 business days from today?" It sounds simple. It isn't.
Date math in JavaScript is already a pain. Add weekends, public holidays, regional variations, and timezone shifts and you've got a bug farm. Let's look at why the obvious solutions break, then build something that actually works.
The Naive Approach (and Why It Fails)
Here's how most developers first tackle "add 10 business days":
function addBusinessDays(date, days) {
const result = new Date(date);
let added = 0;
while (added < days) {
result.setDate(result.getDate() + 1);
if (result.getDay() !== 0 && result.getDay() !== 6) {
added++;
}
}
return result;
}
// Seems to work...
addBusinessDays(new Date('2024-12-20'), 10);
// → 2025-01-03
This skips weekends, which is a start. But it has two serious problems:
- It ignores holidays. Add 10 business days starting December 20 in the US and you'll skip Christmas (Dec 25) and New Year's Day (Jan 1). The real answer is January 7, not January 3.
-
It doesn't handle timezones.
new Date('2024-12-20')parses as UTC midnight, which in a UTC-5 timezone is actually December 19 at 7pm. Your "December 20" calculation is silently off by one.
And the counting direction is just as fragile:
function businessDaysBetween(start, end) {
let count = 0;
const cur = new Date(start);
while (cur < end) {
cur.setDate(cur.getDate() + 1);
if (cur.getDay() !== 0 && cur.getDay() !== 6) count++;
}
return count;
}
businessDaysBetween(new Date('2024-12-23'), new Date('2024-12-27'));
// → 2 (correct for a calendar with no holidays)
// → WRONG in the US — Christmas Eve (Dec 24) is observed, Christmas (Dec 25) is federal
You can patch in a hardcoded holiday list, but then you're maintaining it forever, across every country your app touches.
A Better Approach: Delegate the Calendar Math
BizCal API handles business day calculations for 15 countries with full holiday awareness — including sub-national regions. You make a GET request, you get the answer.
Count Business Days Between Two Dates
async function businessDaysBetween(start, end, country = 'US', region = null) {
const params = new URLSearchParams({ start, end, country });
if (region) params.set('region', region);
const res = await fetch(
`https://bizcalapi.com/business-days/between?${params}`,
{
headers: {
'X-RapidAPI-Key': 'YOUR_API_KEY',
'X-RapidAPI-Host': 'bizcalapi.com',
},
}
);
if (!res.ok) throw new Error(`API error: ${res.status}`);
const data = await res.json();
return data.business_days;
}
// How many business days from Dec 23 to Dec 27 in the US?
const days = await businessDaysBetween('2024-12-23', '2024-12-27', 'US');
console.log(days); // 1 (Dec 24 is observed Christmas Eve, Dec 25 is Christmas)
// Same range in the UK?
const ukDays = await businessDaysBetween('2024-12-23', '2024-12-27', 'GB');
console.log(ukDays); // also accounts for Boxing Day (Dec 26)
Swap the country param and the holiday calendar changes. No hardcoded lists, no maintenance.
Add N Business Days to a Date
async function addBusinessDays(date, days, country = 'US', region = null) {
const params = new URLSearchParams({ date, days, country });
if (region) params.set('region', region);
const res = await fetch(
`https://bizcalapi.com/business-days/add?${params}`,
{
headers: {
'X-RapidAPI-Key': 'YOUR_API_KEY',
'X-RapidAPI-Host': 'bizcalapi.com',
},
}
);
const data = await res.json();
return data.result_date; // "YYYY-MM-DD"
}
// 10 business days from Dec 20 in the US (skips Christmas + New Year)
const due = await addBusinessDays('2024-12-20', 10, 'US');
console.log(due); // "2025-01-07"
// Same calculation for a UK client
const ukDue = await addBusinessDays('2024-12-20', 10, 'GB');
console.log(ukDue); // accounts for Christmas, Boxing Day, New Year
Building a Due Date Calculator
class DueDateCalculator {
constructor(apiKey, country = 'US', region = null) {
this.apiKey = apiKey;
this.country = country;
this.region = region;
this.base = 'https://bizcalapi.com';
this.headers = {
'X-RapidAPI-Key': apiKey,
'X-RapidAPI-Host': 'bizcalapi.com',
};
}
async addDays(startDate, businessDays) {
const params = new URLSearchParams({
date: startDate,
days: businessDays,
country: this.country,
});
if (this.region) params.set('region', this.region);
const res = await fetch(`${this.base}/business-days/add?${params}`, {
headers: this.headers,
});
const data = await res.json();
return {
start: data.start_date,
due: data.result_date,
holidaysSkipped: data.holidays_skipped ?? [],
};
}
async workingDaysLeft(targetDate) {
const today = new Date().toISOString().split('T')[0];
const params = new URLSearchParams({
start: today,
end: targetDate,
country: this.country,
});
if (this.region) params.set('region', this.region);
const res = await fetch(`${this.base}/business-days/between?${params}`, {
headers: this.headers,
});
const data = await res.json();
return data.business_days;
}
}
const calc = new DueDateCalculator('YOUR_API_KEY', 'US', 'CA');
const result = await calc.addDays('2024-12-20', 10);
console.log(`Due: ${result.due}`);
console.log(`Holidays skipped: ${result.holidaysSkipped.join(', ')}`);
US vs. UK: Why the country Param Matters
const range = { start: '2024-12-23', end: '2025-01-03' };
const [us, uk, au] = await Promise.all([
businessDaysBetween(range.start, range.end, 'US'),
businessDaysBetween(range.start, range.end, 'GB'),
businessDaysBetween(range.start, range.end, 'AU'),
]);
console.log(`US: ${us} business days`);
console.log(`UK: ${uk} business days`);
console.log(`AU: ${au} business days`);
If you're building project management software, shipping estimates, or anything that shows dates to users in different countries — this difference matters.
What BizCal Covers
The /business-days/ group has 6 endpoints:
-
/between— count business days between two dates -
/add— add N business days to a date -
/subtract— subtract N business days from a date -
/next— next business day after a date -
/previous— previous business day before a date -
/is-business-day— boolean check for a specific date
All support country and optional region parameters. 15 countries, ~200 regional calendars.
Get Started
Subscribe on RapidAPI: BizCal API
The Free tier gives you 50 requests/day — enough to build and test. Basic is $9.99/mo for 1,000 requests/day across all 15 countries.
Stop maintaining holiday lists. Ship the feature.
Top comments (0)