nhb-toolbox
Version:
A versatile collection of smart, efficient, and reusable utility functions, classes and types for everyday development needs.
149 lines (148 loc) • 7.02 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.businessPlugin = void 0;
const non_primitives_1 = require("../../guards/non-primitives");
const primitives_1 = require("../../guards/primitives");
const constants_1 = require("../constants");
const businessPlugin = ($Chronos) => {
const { internalDate: $Date, withOrigin, cast, offset } = $Chronos[constants_1.INTERNALS];
const _buildWeekendMask = (weekDef, length) => {
const weekendDays = (0, non_primitives_1.isValidArray)(weekDef)
? [...weekDef].sort()
: Array.from({ length }, (_, i) => (weekDef + 7 - 1 - i) % 7).sort();
const mask = new Array(7).fill(true);
for (const d of weekendDays)
mask[d] = false;
return mask;
};
const _countDays = (sWeek, days, mask, step = 1, wd = true) => {
let total = Math.floor(days / 7) * mask.filter((m) => (wd ? Boolean(m) : !m)).length;
let dayIndex = ((sWeek % 7) + 7) % 7;
for (let i = 0; i < days % 7; i++) {
const isMatch = wd ? Boolean(mask[dayIndex]) : !mask[dayIndex];
if (isMatch)
total++;
dayIndex = (dayIndex + step + 7) % 7;
}
return total;
};
$Chronos.prototype.isWeekend = function (wDef = 0, wLen = 2) {
const day = $Date(this).getDay();
if ((0, non_primitives_1.isValidArray)(wDef)) {
return wDef.includes(day);
}
const lastDayOfWeek = (wDef + 6) % 7;
const weekendDays = Array.from({ length: wLen }, (_, i) => (lastDayOfWeek - i + 7) % 7);
return weekendDays.includes(day);
};
$Chronos.prototype.isWorkday = function (wDef = 0, wLen = 2) {
return !this.isWeekend(wDef, wLen);
};
$Chronos.prototype.nextWorkday = function (wDef = 0, wLen = 2) {
let nxtWrk = this.addDays(1);
while (nxtWrk.isWeekend(wDef, wLen)) {
nxtWrk = nxtWrk.addDays(1);
}
return withOrigin(nxtWrk.startOf('day'), 'nextWorkday', offset(this), this.timeZoneName, this.timeZoneId, this.$tzTracker);
};
$Chronos.prototype.previousWorkday = function (wDef = 0, wLen = 2) {
let prevWrk = this.addDays(-1);
while (prevWrk.isWeekend(wDef, wLen)) {
prevWrk = prevWrk.addDays(-1);
}
return withOrigin(prevWrk.startOf('day'), 'previousWorkday', offset(this), this.timeZoneName, this.timeZoneId, this.$tzTracker);
};
$Chronos.prototype.nextWeekend = function (wDef = 0, wLen = 2) {
let nxtWknd = this.addDays(1);
while (!nxtWknd.isWeekend(wDef, wLen)) {
nxtWknd = nxtWknd.addDays(1);
}
return withOrigin(nxtWknd.startOf('day'), 'nextWeekend', offset(this), this.timeZoneName, this.timeZoneId, this.$tzTracker);
};
$Chronos.prototype.previousWeekend = function (wDef = 0, wLen = 2) {
let prevWknd = this.addDays(-1);
while (!prevWknd.isWeekend(wDef, wLen)) {
prevWknd = prevWknd.addDays(-1);
}
return withOrigin(prevWknd.startOf('day'), 'previousWeekend', offset(this), this.timeZoneName, this.timeZoneId, this.$tzTracker);
};
$Chronos.prototype.workdaysBetween = function (to, wDef = 0, wLen = 2) {
const end = cast(to).startOf('day');
const start = this.startOf('day');
if (start.isSame(end, 'day'))
return 0;
const step = start.isBefore(end, 'day') ? 1 : -1;
const totalDays = Math.abs(end.diff(start, 'day'));
const weekendMask = _buildWeekendMask(wDef, wLen);
const startWeekday = (start.isoWeekDay + step) % 7;
return _countDays(startWeekday, totalDays, weekendMask, step);
};
$Chronos.prototype.weekendsBetween = function (to, wDef = 0, wLen = 2) {
const end = cast(to).startOf('day');
const start = this.startOf('day');
if (start.isSame(end, 'day'))
return 0;
const step = start.isBefore(end, 'day') ? 1 : -1;
const totalDays = Math.abs(end.diff(start, 'day'));
const weekendMask = _buildWeekendMask(wDef, wLen);
const startWeekday = (start.isoWeekDay + step) % 7;
return _countDays(startWeekday, totalDays, weekendMask, step, false);
};
$Chronos.prototype.workdaysInMonth = function (wDef = 0, wLen = 2) {
const daysInMonth = this.daysInMonth();
const weekendMask = _buildWeekendMask(wDef, wLen);
const startWeekday = this.startOf('month').isoWeekDay % 7;
return _countDays(startWeekday, daysInMonth, weekendMask);
};
$Chronos.prototype.weekendsInMonth = function (wDef = 0, wLen = 2) {
const daysInMonth = this.daysInMonth();
const weekendMask = _buildWeekendMask(wDef, wLen);
const startWeekday = this.startOf('month').isoWeekDay % 7;
return _countDays(startWeekday, daysInMonth, weekendMask, 1, false);
};
$Chronos.prototype.workdaysInYear = function (wDef = 0, wLen = 2) {
const daysInYear = this.isLeapYear() ? 366 : 365;
const weekendMask = _buildWeekendMask(wDef, wLen);
const startWeekday = this.startOf('year').isoWeekDay % 7;
return _countDays(startWeekday, daysInYear, weekendMask);
};
$Chronos.prototype.weekendsInYear = function (wDef = 0, wLen = 2) {
const daysInYear = this.isLeapYear() ? 366 : 365;
const weekendMask = _buildWeekendMask(wDef, wLen);
const startWeekday = this.startOf('year').isoWeekDay % 7;
return _countDays(startWeekday, daysInYear, weekendMask, 1, false);
};
$Chronos.prototype.isBusinessHour = function (options) {
const _isBusinessHour = () => {
const { businessStartHour = 9, businessEndHour = 17 } = options ?? {};
if (businessStartHour === businessEndHour)
return false;
const hour = $Date(this).getHours();
if (businessStartHour < businessEndHour) {
return hour >= businessStartHour && hour < businessEndHour;
}
else {
return hour >= businessStartHour || hour < businessEndHour;
}
};
if (options && 'weekendDays' in options && !(0, primitives_1.isUndefined)(options?.weekendDays)) {
return this.isWorkday(options.weekendDays) && _isBusinessHour();
}
const { weekStartsOn = 0, weekendLength = 2 } = (options ?? {});
return this.isWorkday(weekStartsOn, weekendLength) && _isBusinessHour();
};
$Chronos.prototype.toFiscalQuarter = function (startMonth = 7) {
const adjusted = (this.isoMonth - startMonth + 12) % 12;
return (Math.floor(adjusted / 3) + 1);
};
$Chronos.prototype.toAcademicYear = function () {
const year = this.year;
if (this.month >= 6) {
return `${year}-${year + 1}`;
}
else {
return `${year - 1}-${year}`;
}
};
};
exports.businessPlugin = businessPlugin;