UNPKG

moment-biz

Version:

Handle business days & weekends over multiple years

64 lines (48 loc) 2.27 kB
'use strict'; const moment = require('moment'); function addSubBuisnessDays(originalCall, direction, val, period, ...args) { if (val < 0) return this[direction === 'add' ? 'subtract' : 'add'](-val, period, ...args); const old = moment(this)[direction === 'add' ? 'startOf' : 'endOf']('day'); // add week-ends const weekends = this.localeData()._config.weekends || [0, 6]; const nbWeekends = Math.floor(val / (7 - weekends.length)); originalCall.call(this, val + nbWeekends * weekends.length, 'day'); // how many week-end days did we miss with the previous naive calculation? const weekendAdjustment = [...Array(val % (7 - weekends.length)).keys()].reduce( (acc, i) => acc + (weekends.indexOf((this.day() + (direction === 'add' ? -i + 7 : i)) % 7) >= 0), 0 ); // adjust last weekend days if needed if (weekendAdjustment) { originalCall.call(this, weekendAdjustment, 'day'); while (this.isWeekend()) originalCall.call(this, 1, 'day'); } // take holidays into account var dayBoundary = moment(this)[direction === 'add' ? 'endOf' : 'startOf']('day'); const addSubIfHolidayÎsValid = date => { // if the holiday is not in the current period (or is on a weekend), ignore it if (!date.isValid() || date.isWeekend() || direction === 'add' && (date <= old || date > dayBoundary) || direction === 'subtract' && (date > old || date <= dayBoundary)) return; this[direction](1, 'businessday'); dayBoundary = moment(this)[direction === 'add' ? 'endOf' : 'startOf']('day'); }; for (let year = old.year(); year <= this.year(); ++year) moment.getHolidays(year, this.locale()).forEach(addSubIfHolidayÎsValid); return this; } const momentAdd = moment.fn.add; moment.fn.add = function(val, period) { if (period !== 'businessday' && period !== 'businessdays') return momentAdd.call(this, ...arguments); return addSubBuisnessDays.call(this, momentAdd, 'add', ...arguments); }; const momentSubtract = moment.fn.subtract; moment.fn.subtract = function(val, period) { if (period !== 'businessday' && period !== 'businessdays') return momentSubtract.call(this, ...arguments); return addSubBuisnessDays.call(this, momentSubtract, 'subtract', ...arguments); };