js-06-business-days
1.000
Challenge · difficulty 4/5
# Business days between (date-fns)
Implement an ES module **`solution.js`** that uses **date-fns** (already installed — import it):
```js
import { parseISO, eachDayOfInterval, isWeekend } from "date-fns";
export function businessDaysBetween(startISO, endISO) { /* ... */ }
```
Given two ISO date strings (`"YYYY-MM-DD"`), count the number of **business days**
(weekdays Monday–Friday) in the range **(start, end]** — that is, **exclusive of the
start date and inclusive of the end date**.
Rules:
- Saturday and Sunday are not business days.
- The start date itself is never counted (even if it is a weekday).
- The end date is counted if it is a weekday.
- If `end <= start`, return `0`.
Use date-fns helpers such as `parseISO`, `eachDayOfInterval`, and `isWeekend`.
Examples:
```js
businessDaysBetween("2024-01-01", "2024-01-05") // => 4
// Mon..Fri: start Mon excluded; Tue, Wed, Thu, Fri counted
businessDaysBetween("2024-01-05", "2024-01-08") // => 1
// Fri..Mon: Fri excluded, Sat/Sun weekend, Mon counted
businessDaysBetween("2024-01-01", "2024-01-01") // => 0
// same day
businessDaysBetween("2024-01-01", "2024-01-08") // => 5
// one week: Mon excluded; Tue–Fri (4) + next Mon (1)
```
tests/solution.test.js
import { test } from "node:test";
import { strict as assert } from "node:assert";
import { businessDaysBetween } from "./solution.js";
test("Mon..Fri excludes start, counts Tue-Fri", () => {
assert.equal(businessDaysBetween("2024-01-01", "2024-01-05"), 4);
});
test("Fri..Mon skips the weekend, counts Mon", () => {
assert.equal(businessDaysBetween("2024-01-05", "2024-01-08"), 1);
});
test("same day -> 0", () => {
assert.equal(businessDaysBetween("2024-01-01", "2024-01-01"), 0);
});
test("end before start -> 0", () => {
assert.equal(businessDaysBetween("2024-01-10", "2024-01-01"), 0);
});
test("one full week (Mon..Mon) -> 5", () => {
assert.equal(businessDaysBetween("2024-01-01", "2024-01-08"), 5);
});
test("range entirely within a weekend -> 0", () => {
// Sat 2024-01-06 .. Sun 2024-01-07
assert.equal(businessDaysBetween("2024-01-06", "2024-01-07"), 0);
});
test("start on a weekend still excludes start, counts weekdays after", () => {
// Sat 2024-01-06 .. Fri 2024-01-12: Mon-Fri (5) counted
assert.equal(businessDaysBetween("2024-01-06", "2024-01-12"), 5);
});
test("two weeks spanning two weekends", () => {
// Mon 2024-01-01 .. Mon 2024-01-15: exclude first Mon.
// Tue-Fri wk1 (4) + Mon-Fri wk2 (5) + final Mon (1) = 10
assert.equal(businessDaysBetween("2024-01-01", "2024-01-15"), 10);
});
System prompt
You are an expert programmer. Solve the task exactly as specified. Output your solution as fenced code blocks using the required file name(s) and the exact function/type signatures requested. Prefer correctness; do not include prose outside code unless asked.
Proposed solution
```js
import { parseISO, eachDayOfInterval, isWeekend } from "date-fns";
export function businessDaysBetween(startISO, endISO) {
const start = parseISO(startISO);
const end = parseISO(endISO);
if (end <= start) {
return 0;
}
let count = 0;
for (const day of eachDayOfInterval({ start, end })) {
if (!isWeekend(day)) {
count++;
}
}
// Exclude the start date if it's a weekday
const startDate = parseISO(startISO);
if (!isWeekend(startDate)) {
count--;
}
return count;
}
```Test output (stdout)
TAP version 13 # Subtest: Mon..Fri excludes start, counts Tue-Fri ok 1 - Mon..Fri excludes start, counts Tue-Fri --- duration_ms: 1.922652 type: 'test' ... # Subtest: Fri..Mon skips the weekend, counts Mon ok 2 - Fri..Mon skips the weekend, counts Mon --- duration_ms: 0.09489 type: 'test' ... # Subtest: same day -> 0 ok 3 - same day -> 0 --- duration_ms: 0.053331 type: 'test' ... # Subtest: end before start -> 0 ok 4 - end before start -> 0 --- duration_ms: 0.06618 type: 'test' ... # Subtest: one full week (Mon..Mon) -> 5 ok 5 - one full week (Mon..Mon) -> 5 --- duration_ms: 0.075451 type: 'test' ... # Subtest: range entirely within a weekend -> 0 ok 6 - range entirely within a weekend -> 0 --- duration_ms: 0.05955 type: 'test' ... # Subtest: start on a weekend still excludes start, counts weekdays after ok 7 - start on a weekend still excludes start, counts weekdays after --- duration_ms: 0.051601 type: 'test' ... # Subtest: two weeks spanning two weekends ok 8 - two weeks spanning two weekends --- duration_ms: 0.04914 type: 'test' ... 1..8 # tests 8 # suites 0 # pass 8 # fail 0 # cancelled 0 # skipped 0 # todo 0 # duration_ms 534.307993