@eristack/business-calendar
Version:
Business days and holidays on YYYY-MM-DD wall dates — no timestamp import in core
139 lines (135 loc) • 4.53 kB
JavaScript
;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/index.ts
var index_exports = {};
__export(index_exports, {
BusinessCalendarParseError: () => BusinessCalendarParseError,
addWallDays: () => addWallDays,
createBusinessCalendar: () => createBusinessCalendar,
normalizeWallDate: () => normalizeWallDate,
wallDateDayOfWeek: () => wallDateDayOfWeek
});
module.exports = __toCommonJS(index_exports);
// src/core/errors.ts
var BusinessCalendarParseError = class extends Error {
code = "BUSINESS_CALENDAR_PARSE_ERROR";
constructor(message) {
super(message);
this.name = "BusinessCalendarParseError";
}
};
// src/core/wall-date.ts
var WALL_DATE_RE = /^(\d{4})-(\d{2})-(\d{2})$/;
function normalizeWallDate(value) {
const trimmed = value.trim();
const match = WALL_DATE_RE.exec(trimmed);
if (!match) {
throw new BusinessCalendarParseError(
`Invalid wall date "${value}" \u2014 expected YYYY-MM-DD`
);
}
const year = Number(match[1]);
const month = Number(match[2]);
const day = Number(match[3]);
const utc = Date.UTC(year, month - 1, day);
const check = new Date(utc);
if (check.getUTCFullYear() !== year || check.getUTCMonth() !== month - 1 || check.getUTCDate() !== day) {
throw new BusinessCalendarParseError(`Invalid calendar date "${value}"`);
}
const mm = String(month).padStart(2, "0");
const dd = String(day).padStart(2, "0");
return `${year}-${mm}-${dd}`;
}
function wallDateDayOfWeek(date) {
const normalized = normalizeWallDate(date);
const [y, m, d] = normalized.split("-").map(Number);
return new Date(Date.UTC(y, m - 1, d)).getUTCDay();
}
function addWallDays(date, days) {
const normalized = normalizeWallDate(date);
const [y, m, d] = normalized.split("-").map(Number);
const next = new Date(Date.UTC(y, m - 1, d));
next.setUTCDate(next.getUTCDate() + days);
const ny = next.getUTCFullYear();
const nm = String(next.getUTCMonth() + 1).padStart(2, "0");
const nd = String(next.getUTCDate()).padStart(2, "0");
return `${ny}-${nm}-${nd}`;
}
// src/core/calendar.ts
function normalizeWeekendDays(days) {
const set = /* @__PURE__ */ new Set();
for (const day of days) {
if (!Number.isInteger(day) || day < 0 || day > 6) {
throw new BusinessCalendarParseError(
`weekendDays entry ${day} must be an integer 0\u20136 (Sun\u2013Sat)`
);
}
set.add(day);
}
return set;
}
function createBusinessCalendar(options) {
const weekendDays = normalizeWeekendDays(options.weekendDays);
const holidays = new Set(
options.holidays.map((h) => normalizeWallDate(h))
);
function isBusinessDay(date) {
const wall = normalizeWallDate(date);
if (holidays.has(wall)) {
return false;
}
const dow = wallDateDayOfWeek(wall);
return !weekendDays.has(dow);
}
function nextBusinessDay(date) {
let cursor = normalizeWallDate(date);
do {
cursor = addWallDays(cursor, 1);
} while (!isBusinessDay(cursor));
return cursor;
}
function addBusinessDays(date, days) {
if (!Number.isInteger(days)) {
throw new BusinessCalendarParseError("days must be an integer");
}
let cursor = normalizeWallDate(date);
if (days === 0) {
return cursor;
}
const step = days > 0 ? 1 : -1;
let remaining = Math.abs(days);
while (remaining > 0) {
cursor = addWallDays(cursor, step);
if (isBusinessDay(cursor)) {
remaining -= 1;
}
}
return cursor;
}
return { isBusinessDay, nextBusinessDay, addBusinessDays };
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
BusinessCalendarParseError,
addWallDays,
createBusinessCalendar,
normalizeWallDate,
wallDateDayOfWeek
});
//# sourceMappingURL=index.cjs.map