UNPKG

2.71 kBJavaScriptView Raw
1import { normalizeDates } from "./_lib/normalizeDates.js";
2import { addDays } from "./addDays.js";
3import { differenceInCalendarDays } from "./differenceInCalendarDays.js";
4import { isSameDay } from "./isSameDay.js";
5import { isValid } from "./isValid.js";
6import { isWeekend } from "./isWeekend.js";
7
8/**
9 * The {@link differenceInBusinessDays} function options.
10 */
11
12/**
13 * @name differenceInBusinessDays
14 * @category Day Helpers
15 * @summary Get the number of business days between the given dates.
16 *
17 * @description
18 * Get the number of business day periods between the given dates.
19 * Business days being days that aren't in the weekend.
20 * Like `differenceInCalendarDays`, the function removes the times from
21 * the dates before calculating the difference.
22 *
23 * @param laterDate - The later date
24 * @param earlierDate - The earlier date
25 * @param options - An object with options
26 *
27 * @returns The number of business days
28 *
29 * @example
30 * // How many business days are between
31 * // 10 January 2014 and 20 July 2014?
32 * const result = differenceInBusinessDays(
33 * new Date(2014, 6, 20),
34 * new Date(2014, 0, 10)
35 * )
36 * //=> 136
37 *
38 * // How many business days are between
39 * // 30 November 2021 and 1 November 2021?
40 * const result = differenceInBusinessDays(
41 * new Date(2021, 10, 30),
42 * new Date(2021, 10, 1)
43 * )
44 * //=> 21
45 *
46 * // How many business days are between
47 * // 1 November 2021 and 1 December 2021?
48 * const result = differenceInBusinessDays(
49 * new Date(2021, 10, 1),
50 * new Date(2021, 11, 1)
51 * )
52 * //=> -22
53 *
54 * // How many business days are between
55 * // 1 November 2021 and 1 November 2021 ?
56 * const result = differenceInBusinessDays(
57 * new Date(2021, 10, 1),
58 * new Date(2021, 10, 1)
59 * )
60 * //=> 0
61 */
62export function differenceInBusinessDays(laterDate, earlierDate, options) {
63 const [laterDate_, earlierDate_] = normalizeDates(
64 options?.in,
65 laterDate,
66 earlierDate,
67 );
68
69 if (!isValid(laterDate_) || !isValid(earlierDate_)) return NaN;
70
71 const diff = differenceInCalendarDays(laterDate_, earlierDate_);
72 const sign = diff < 0 ? -1 : 1;
73 const weeks = Math.trunc(diff / 7);
74
75 let result = weeks * 5;
76 let movingDate = addDays(earlierDate_, weeks * 7);
77
78 // the loop below will run at most 6 times to account for the remaining days that don't makeup a full week
79 while (!isSameDay(laterDate_, movingDate)) {
80 // sign is used to account for both negative and positive differences
81 result += isWeekend(movingDate, options) ? 0 : sign;
82 movingDate = addDays(movingDate, sign);
83 }
84
85 // Prevent negative zero
86 return result === 0 ? 0 : result;
87}
88
89// Fallback for modularized imports:
90export default differenceInBusinessDays;