Hi! May I seek for your help on how to calculate the number of days between two dates excluding weekends and public holidays using javascript. Also, how to calculate the end date (start date and duration given) excluding weekends and public holidays. Thank you.
manay 0 Newbie Poster
Dani AI
Generated
As requested, below is a compact, reliable JavaScript approach that (1) counts business days between two dates (weekends + a supplied list of public holidays excluded) and (2) computes an end date given a start date and a duration measured in business days. This version normalizes dates to UTC-midnight (avoiding DST/timezone drift), supports inclusive/exclusive semantics, and expects holidays as explicit 'YYYY-MM-DD' entries. (As asked, date parsing is handled; thanks to for pointing to related solutions.)
// Simple, correct utilities using UTC-normalized day numbers.
// Inputs: Date objects or 'YYYY-MM-DD' strings. Holidays: ['YYYY-MM-DD', ...].
const MS_PER_DAY = 24 * 60 * 60 * 1000;
function toDayNumber(d) {
if (d instanceof Date) {
return Math.floor(Date.UTC(d.getFullYear(), d.getMonth(), d.getDate()) / MS_PER_DAY);
}
if (typeof d === 'string') {
const parts = d.split('-').map(Number);
if (parts.length !== 3) throw new Error('Date string must be YYYY-MM-DD');
return Math.floor(Date.UTC(parts[0], parts[1] - 1, parts[2]) / MS_PER_DAY);
}
throw new Error('toDayNumber accepts Date or YYYY-MM-DD string');
}
function dayNumberToDate(n) {
return new Date(n * MS_PER_DAY);
}
function isWeekendDayNumber(n) {
const dow = new Date(n * MS_PER_DAY).getUTCDay(); // 0 = Sun, 6 = Sat
return dow === 0 || dow === 6;
}
function businessDaysBetween(start, end, holidays = [], opts) {
const inclusive = opts && typeof opts.inclusive === 'boolean' ? opts.inclusive : true;
let a = toDayNumber(start), b = toDayNumber(end);
if (a > b) { const t = a; a = b; b = t; }
if (!inclusive) { a += 1; b -= 1; }
if (a > b) return 0;
const days = b - a + 1;
const wholeWeeks = Math.floor(days / 7);
let business = wholeWeeks * 5;
const extra = days % 7;
const startDow = new Date(a * MS_PER_DAY).getUTCDay();
for (let i = 0; i < extra; i++) {
const dow = (startDow + i) % 7;
if (dow !== 0 && dow !== 6) business++;
}
const holidaySet = new Set(holidays.map(h => toDayNumber(h)));
for (const h of holidaySet) {
if (h >= a && h <= b) {
const dow = new Date(h * MS_PER_DAY).getUTCDay();
if (dow !== 0 && dow !== 6) business--;
}
}
return Math.max(0, business);
}
function addBusinessDays(start, businessDays, holidays = [], opts) {
if (!Number.isInteger(businessDays)) throw new Error('businessDays must be an integer');
const includeStart = opts && typeof opts.includeStart === 'boolean' ? opts.includeStart : true;
const sign = businessDays >= 0 ? 1 : -1;
let remaining = Math.abs(businessDays);
const holidaySet = new Set(holidays.map(h => toDayNumber(h)));
let candidate = toDayNumber(start);
candidate = includeStart ? candidate : candidate + sign;
if (remaining === 0) {
while (isWeekendDayNumber(candidate) || holidaySet.has(candidate)) candidate += sign;
return dayNumberToDate(candidate);
}
while (true) {
if (!isWeekendDayNumber(candidate) && !holidaySet.has(candidate)) {
remaining--;
if (remaining === 0) return dayNumberToDate(candidate);
}
candidate += sign;
}
} Notes and troubleshooting
- Input conventions: use Date objects or 'YYYY-MM-DD' strings; holidays must be explicit dates (include observed dates if a holiday shifts from a weekend). The code treats holidays falling on weekends as already excluded (only weekday holidays reduce the count).
- Semantics:
businessDaysBetweendefaults to inclusive endpoints (pass{ inclusive: false }to exclude).addBusinessDays(..., n)treatsstartas day 1 by default; pass{ includeStart: false }to start counting from the following business day. - Timezones: normalization to UTC-midnight avoids DST/local-offset problems. Always provide date-only values when possible.
- Performance: counting uses week arithmetic (no per-day loop) except when advancing by N business days; the latter uses a simple loop which is fine for typical durations. For very large distances, accelerate by adding whole weeks and then correcting for holidays (requires counting holidays inside the fast-forwarded span).
- Custom weekends: for locales with different weekend days, adjust
isWeekendDayNumberaccordingly.
Edge cases covered: start > end, zero-length intervals, negative durations, and duplicate holiday entries (deduplicated via Set).
Recommended Answers
Jump to Post— pritaeas 2,276What do you have so far?
All 2 Replies
pritaeas 2,276 Most Valuable Poster Moderator Featured Poster
What do you have so far?
AlbertinaGeller 0 Newbie Poster
I have found something similar to your asked question. You can try it and and see if you are getting the things that you want.
https://stackoverflow.com/questions/37069186/calculate-working-days-between-two-dates-in-javascript-excepts-holidays
Be a part of the DaniWeb community
We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.