import { addDays, isWeekend, parseISO, format, isWithinInterval } from "date-fns" import type { WorkdayExceptionData } from "./types" function isExceptionDay( date: Date, exceptions: WorkdayExceptionData[] ): boolean { return exceptions.some((ex) => { const start = parseISO(ex.startDate) const end = parseISO(ex.endDate) return isWithinInterval(date, { start, end }) }) } function isNonWorkday( date: Date, exceptions: WorkdayExceptionData[] = [] ): boolean { return isWeekend(date) || isExceptionDay(date, exceptions) } export function calculateEndDate( startDate: string, workdays: number, exceptions: WorkdayExceptionData[] = [] ): string { if (workdays <= 0) return startDate let current = parseISO(startDate) let remaining = workdays if (!isNonWorkday(current, exceptions)) { remaining-- } while (remaining > 0) { current = addDays(current, 1) if (!isNonWorkday(current, exceptions)) { remaining-- } } return format(current, "yyyy-MM-dd") } export function countBusinessDays( startDate: string, endDate: string, exceptions: WorkdayExceptionData[] = [] ): number { let current = parseISO(startDate) const end = parseISO(endDate) let count = 0 while (current <= end) { if (!isNonWorkday(current, exceptions)) { count++ } current = addDays(current, 1) } return count } export function addBusinessDays( date: string, days: number, exceptions: WorkdayExceptionData[] = [] ): string { let current = parseISO(date) let remaining = Math.abs(days) const direction = days >= 0 ? 1 : -1 while (remaining > 0) { current = addDays(current, direction) if (!isNonWorkday(current, exceptions)) { remaining-- } } return format(current, "yyyy-MM-dd") }