dutyhours
Version:
A tool to calculate total working hours in a given month, taking into account public holidays and configurable working days.
1 lines • 6.19 kB
Source Map (JSON)
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import Holidays from 'date-holidays';\n\nexport interface Options {\n /**\n * The country code to determine the public holidays. In ISO 3166-1 alpha-2 format.\n * For example, 'US' for United States, 'PL' for Poland, etc.\n * @type {string}\n */\n country: string;\n\n /**\n * The number of working hours in a single working day.\n * @type {number}\n * @default 8\n *\n */\n hoursPerDay?: number;\n\n /**\n * Whether to include Mondays as working days.\n * @type {boolean}\n * @default true\n */\n withMondays?: boolean;\n\n /**\n * Whether to include Tuesdays as working days.\n * @type {boolean}\n * @default true\n */\n withTuesdays?: boolean;\n\n /**\n * Whether to include Wednesdays as working days.\n * @type {boolean}\n * @default true\n */\n withWednesdays?: boolean;\n\n /**\n * Whether to include Thursdays as working days.\n * @type {boolean}\n * @default true\n */\n withThursdays?: boolean;\n\n /**\n * Whether to include Fridays as working days.\n * @type {boolean}\n * @default true\n */\n withFridays?: boolean;\n\n /**\n * Whether to include Saturdays as working days.\n * @type {boolean}\n * @default false\n */\n withSaturdays?: boolean;\n\n /**\n * Whether to include Sundays as working days.\n * @type {boolean}\n * @default false\n */\n withSundays?: boolean;\n\n /**\n * Whether to exclude Mondays from working days.\n * @type {boolean}\n * @default false\n */\n withoutMondays?: boolean;\n\n /**\n * Whether to exclude Tuesdays from working days.\n * @type {boolean}\n * @default false\n */\n withoutTuesdays?: boolean;\n\n /**\n * Whether to exclude Wednesdays from working days.\n * @type {boolean}\n * @default false\n */\n withoutWednesdays?: boolean;\n\n /**\n * Whether to exclude Thursdays from working days.\n * @type {boolean}\n * @default false\n */\n withoutThursdays?: boolean;\n\n /**\n * Whether to exclude Fridays from working days.\n * @type {boolean}\n * @default false\n */\n withoutFridays?: boolean;\n\n /**\n * Whether to exclude Saturdays from working days.\n * @type {boolean}\n * @default true\n */\n withoutSaturdays?: boolean;\n\n /**\n * Whether to exclude Sundays from working days.\n * @type {boolean}\n * @default true\n */\n withoutSundays?: boolean;\n\n /**\n * The month (indexed from 1 to 12) to calculate working hours for. Defaults to the current month.\n * @type {number}\n */\n month?: number;\n\n /**\n * The year to calculate working hours for. Defaults to the current year.\n * @type {number}\n */\n year?: number;\n}\n\nconst DAY_NAMES = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'] as const;\n\ntype DayName = (typeof DAY_NAMES)[number];\n\nfunction isWorkingDay(dayIndex: number, options: Options): boolean {\n const dayName = DAY_NAMES[dayIndex] as DayName;\n\n if (options[`without${dayName}s` as keyof Options]) return false;\n if (options[`with${dayName}s` as keyof Options]) return true;\n\n // Default to Monday-Friday as working days\n return dayIndex >= 1 && dayIndex <= 5;\n}\n\nfunction getHolidaysForMonth(year: number, month: number, country: string): Set<string> {\n const hd = new Holidays(country);\n const startOfMonth = new Date(year, month - 1, 1);\n const endOfMonth = new Date(year, month, 0);\n\n return new Set(\n hd\n .getHolidays(year)\n .filter(({ date, type }) => {\n const holidayDate = new Date(date);\n return holidayDate >= startOfMonth && holidayDate <= endOfMonth && type !== 'observance';\n })\n .map(({ date }) => new Date(date).toDateString())\n );\n}\n\n/**\n * Calculates the total number of working hours in a given month.\n * @param options Configuration options\n * @returns Total working hours\n */\nfunction calculateWorkingHours(options: Options): number {\n const today = new Date();\n const { country, hoursPerDay = 8, month = today.getMonth() + 1, year = today.getFullYear() } = options;\n\n const holidays = getHolidaysForMonth(year, month, country);\n const endOfMonth = new Date(year, month, 0);\n\n let workingHours = 0;\n\n for (let day = 1; day <= endOfMonth.getDate(); day++) {\n const currentDate = new Date(year, month - 1, day);\n const dayIndex = currentDate.getDay();\n\n if (!holidays.has(currentDate.toDateString()) && isWorkingDay(dayIndex, options)) {\n workingHours += hoursPerDay;\n }\n }\n\n return workingHours;\n}\n\nexport default calculateWorkingHours;\n"],"mappings":"0jBAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,aAAAE,IAAA,eAAAC,EAAAH,GAAA,IAAAI,EAAqB,8BAiIfC,EAAY,CAAC,SAAU,SAAU,UAAW,YAAa,WAAY,SAAU,UAAU,EAI/F,SAASC,EAAaC,EAAkBC,EAA2B,CACjE,IAAMC,EAAUJ,EAAUE,CAAQ,EAElC,OAAIC,EAAQ,UAAUC,CAAO,GAAoB,EAAU,GACvDD,EAAQ,OAAOC,CAAO,GAAoB,EAAU,GAGjDF,GAAY,GAAKA,GAAY,CACtC,CAEA,SAASG,EAAoBC,EAAcC,EAAeC,EAA8B,CACtF,IAAMC,EAAK,IAAI,EAAAC,QAASF,CAAO,EACzBG,EAAe,IAAI,KAAKL,EAAMC,EAAQ,EAAG,CAAC,EAC1CK,EAAa,IAAI,KAAKN,EAAMC,EAAO,CAAC,EAE1C,OAAO,IAAI,IACTE,EACG,YAAYH,CAAI,EAChB,OAAO,CAAC,CAAE,KAAAO,EAAM,KAAAC,CAAK,IAAM,CAC1B,IAAMC,EAAc,IAAI,KAAKF,CAAI,EACjC,OAAOE,GAAeJ,GAAgBI,GAAeH,GAAcE,IAAS,YAC9E,CAAC,EACA,IAAI,CAAC,CAAE,KAAAD,CAAK,IAAM,IAAI,KAAKA,CAAI,EAAE,aAAa,CAAC,CACpD,CACF,CAOA,SAASG,EAAsBb,EAA0B,CACvD,IAAMc,EAAQ,IAAI,KACZ,CAAE,QAAAT,EAAS,YAAAU,EAAc,EAAG,MAAAX,EAAQU,EAAM,SAAS,EAAI,EAAG,KAAAX,EAAOW,EAAM,YAAY,CAAE,EAAId,EAEzFgB,EAAWd,EAAoBC,EAAMC,EAAOC,CAAO,EACnDI,EAAa,IAAI,KAAKN,EAAMC,EAAO,CAAC,EAEtCa,EAAe,EAEnB,QAASC,EAAM,EAAGA,GAAOT,EAAW,QAAQ,EAAGS,IAAO,CACpD,IAAMC,EAAc,IAAI,KAAKhB,EAAMC,EAAQ,EAAGc,CAAG,EAC3CnB,EAAWoB,EAAY,OAAO,EAEhC,CAACH,EAAS,IAAIG,EAAY,aAAa,CAAC,GAAKrB,EAAaC,EAAUC,CAAO,IAC7EiB,GAAgBF,EAEpB,CAEA,OAAOE,CACT,CAEA,IAAOvB,EAAQmB","names":["src_exports","__export","src_default","__toCommonJS","import_date_holidays","DAY_NAMES","isWorkingDay","dayIndex","options","dayName","getHolidaysForMonth","year","month","country","hd","Holidays","startOfMonth","endOfMonth","date","type","holidayDate","calculateWorkingHours","today","hoursPerDay","holidays","workingHours","day","currentDate"]}