@scmmishra/business-hours
Version:
Compute business hours like a pro
1 lines • 9.31 kB
Source Map (JSON)
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * Get the start and end time boundaries for a given date based on the provided start and end time strings.\n * @param start - The start time string in the format \"HH:mm\".\n * @param end - The end time string in the format \"HH:mm\".\n * @param date - The date for which the boundaries are calculated.\n * @returns An array containing the start and end time boundaries as Date objects.\n */\nfunction getBoundaries(start: string, end: string, date: Date) {\n const [startHour, startMinute] = start.split(\":\").map(Number);\n const [endHour, endMinute] = end.split(\":\").map(Number);\n\n const startTime = new Date(date);\n startTime.setHours(startHour, startMinute, 0, 0);\n\n const endTime = new Date(date);\n endTime.setHours(endHour, endMinute, 0, 0);\n\n return [startTime, endTime];\n}\n\n/**\n * Add a specified number of seconds to a given date.\n * @param date - The date to which the seconds are added.\n * @param seconds - The number of seconds to add.\n * @returns A new Date object with the added seconds.\n */\nfunction addSeconds(date: Date, seconds: number): Date {\n return new Date(date.getTime() + seconds * 1000);\n}\n\n/**\n * Represents a scheduler that manages working hours and holidays.\n */\nexport class Scheduler {\n private hours: {\n [day: number]: Array<{ start: string; end: string }> | null;\n };\n private holidays: Date[];\n\n /**\n * Creates a new instance of the Scheduler.\n * @param config - The configuration object containing working hours and holidays.\n */\n constructor(config: {\n hours: { [day: number]: Array<{ start: string; end: string }> | null };\n holidays: Date[];\n }) {\n this.hours = config.hours;\n this.holidays = config.holidays;\n }\n\n /**\n * Checks if a given date is a working day.\n * @param date - The date to check.\n * @returns True if the date is a working day, false otherwise.\n */\n public isWorkingDay(date: Date): boolean {\n if (this.isHoliday(date)) {\n return false;\n }\n const workingHours = this.getWorkingHours(date);\n return workingHours !== null && workingHours.length > 0;\n }\n\n /**\n * Checks if a given date and time is within working hours.\n * @param date - The date and time to check.\n * @returns True if the date and time is within working hours, false otherwise.\n */\n public isWorkingTime(date: Date): boolean {\n if (!this.isWorkingDay(date)) {\n return false;\n }\n\n const workingHours = this.getWorkingHours(date);\n if (workingHours) {\n for (const { start, end } of workingHours) {\n const [startTime, endTime] = getBoundaries(start, end, date);\n\n if (date >= startTime && date <= endTime) {\n return true;\n }\n }\n }\n\n return false;\n }\n\n /**\n * Checks if a given date is a holiday.\n * @param date - The date to check.\n * @returns True if the date is a holiday, false otherwise.\n */\n public isHoliday(date: Date): boolean {\n const dateOnly = date.toDateString();\n return this.holidays.some((holiday) => holiday.toDateString() === dateOnly);\n }\n\n public nextWorkingTime(date: Date): Date {\n let nextTime = new Date(date);\n if (!this.isWorkingTime(nextTime)) {\n nextTime = this.nextWorkingDay(nextTime);\n\n const workingHours = this.hours[nextTime.getDay()];\n if (workingHours) {\n const [startHour, startMinute] = workingHours[0].start\n .split(\":\")\n .map(Number);\n\n nextTime.setHours(startHour, startMinute, 0, 0);\n }\n }\n\n // since it is in the same working time\n return nextTime;\n }\n\n /**\n * Get the next working day after a given date.\n * @param date - The date after which the next working day is calculated.\n * @returns The next working day as a Date object.\n */\n public nextWorkingDay(date: Date): Date {\n let nextDay = new Date(date);\n nextDay.setDate(nextDay.getDate() + 1);\n\n while (!this.isWorkingDay(nextDay)) {\n nextDay.setDate(nextDay.getDate() + 1);\n }\n\n return nextDay;\n }\n\n /**\n * Get the remaining working time for a given date.\n * @param date - The date for which the remaining working time is calculated.\n * @returns The remaining working time in seconds.\n */\n public getRemainingWorkingTime(date: Date): number {\n const workingHours = this.getWorkingHours(date);\n\n if (workingHours) {\n for (const { start, end } of workingHours) {\n const [startTime, endTime] = getBoundaries(start, end, date);\n\n if (date >= startTime && date < endTime) {\n return Math.floor((endTime.getTime() - date.getTime()) / 1000);\n }\n }\n }\n\n return 0;\n }\n\n /**\n * Get the elapsed working time for a given date.\n * @param date - The date for which the elapsed working time is calculated.\n * @returns The elapsed working time in seconds.\n */\n public getElapsedWorkingTime(date: Date): number {\n const workingHours = this.getWorkingHours(date);\n\n if (workingHours) {\n for (const { start, end } of workingHours) {\n const [startTime, endTime] = getBoundaries(start, end, date);\n\n if (date >= startTime && date < endTime) {\n return Math.floor((date.getTime() - startTime.getTime()) / 1000);\n }\n }\n }\n\n return 0;\n }\n\n /**\n * Add a specified number of seconds to a given date.\n * @param date - The date to which the seconds are added.\n * @param seconds - The number of seconds to add.\n * @returns A new Date object with the added seconds.\n */\n public addTime(date: Date, seconds: number): Date {\n let newDate = new Date(date);\n let remainingSeconds = seconds;\n\n while (remainingSeconds > 0) {\n const currentDayWorkingTime = this.getRemainingWorkingTime(newDate);\n\n if (remainingSeconds <= currentDayWorkingTime) {\n newDate = addSeconds(newDate, remainingSeconds);\n remainingSeconds = 0;\n } else {\n remainingSeconds -= currentDayWorkingTime;\n newDate = this.nextWorkingTime(newDate);\n }\n }\n\n return newDate;\n }\n\n /**\n * Get the working hours for a given date.\n * @param date - The date for which the working hours are retrieved.\n * @returns The working hours for the given date.\n */\n private getWorkingHours(date: Date) {\n const dayOfWeek = date.getDay();\n return this.hours[dayOfWeek];\n }\n}\n"],"mappings":"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","names":["getBoundaries","start","end","date","startHour","startMinute","endHour","endMinute","startTime","endTime","addSeconds","seconds","Scheduler","config","__publicField","workingHours","dateOnly","holiday","nextTime","nextDay","newDate","remainingSeconds","currentDayWorkingTime","dayOfWeek"]}