get_business_days
Calculate business days between two dates, excluding weekends and custom holidays, for accurate scheduling and planning. Supports timezone adjustments for precision.
Instructions
Calculate business days between dates
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| end_date | Yes | End date | |
| exclude_weekends | No | Exclude weekends (default: true) | |
| holidays | No | Array of holiday dates | |
| start_date | Yes | Start date | |
| timezone | No | Timezone for calculation (default: system timezone) |
Implementation Reference
- src/tools/getBusinessDays.ts:27-146 (handler)Core implementation of getBusinessDays tool handler. Parses dates, aggregates holidays from calendars and custom lists, categorizes days (business/weekend/holiday), applies weekend exclusion, caches results, and returns counts.export function getBusinessDays(params: GetBusinessDaysParams): GetBusinessDaysResult { const { start_date, end_date, holidays = [], holiday_calendar, custom_holidays = [] } = params; // Log entry with all parameters to show what was provided debug.business('getBusinessDays called with params: %O', { start_date, end_date, timezone: params.timezone, exclude_weekends: params.exclude_weekends, holiday_calendar, holidays_count: holidays.length, custom_holidays_count: custom_holidays.length, }); // Important: Log if no country parameter provided but holidays expected if (!holiday_calendar && holidays.length === 0 && custom_holidays.length === 0) { debug.validation('No holiday information provided (no country/calendar, no explicit holidays)'); } // Validate string lengths and array lengths first validateDateString(start_date, 'start_date'); validateDateString(end_date, 'end_date'); validateArrayLength(holidays, LIMITS.MAX_ARRAY_LENGTH, 'holidays'); validateArrayLength(custom_holidays, LIMITS.MAX_ARRAY_LENGTH, 'custom_holidays'); const excludeWeekends = params.exclude_weekends ?? true; const includeObserved = params.include_observed ?? true; const config = getConfig(); const timezone = resolveTimezone(params.timezone, config.defaultTimezone); debug.timezone('Resolved timezone: %s (from: %s)', timezone, params.timezone ?? 'default'); // Build cache key using new utility const cacheKey = buildCacheKey('business', { single: { timezone }, dates: [start_date, end_date], flags: { excludeWeekends, includeObserved }, arrays: { holidays, customHolidays: custom_holidays }, optional: { calendar: holiday_calendar }, }); // Use withCache wrapper return withCache(cacheKey, CacheTTL.BUSINESS_DAYS, () => { // Validate timezone if provided if (timezone && !validateTimezone(timezone)) { debug.error('Invalid timezone: %s', timezone); throw new TimezoneError(`Invalid timezone: ${timezone}`, timezone); } // Validate holiday_calendar if provided if (holiday_calendar) { validateHolidayCalendar(holiday_calendar); } // Parse dates const startDate = parseDateWithTimezone(start_date, timezone, 'start_date'); const endDate = parseDateWithTimezone(end_date, timezone, 'end_date'); // DoS protection: Validate date range validateDateRange(startDate, endDate, start_date, end_date); // Log calculation context debug.business( 'Business days calculation: %s to %s', format(startDate, 'yyyy-MM-dd'), format(endDate, 'yyyy-MM-dd') ); // Use the new holidayAggregator utility debug.holidays('Aggregating holidays for calendar: %s', holiday_calendar ?? 'none'); const allHolidayDates = aggregateHolidays({ calendar: holiday_calendar, includeObserved, dateRange: { start: startDate, end: endDate, }, custom: custom_holidays, legacy: holidays, timezone, }); debug.holidays('Total holidays found: %d', allHolidayDates.size); if (allHolidayDates.size > 0) { debug.holidays('Holiday dates: %O', Array.from(allHolidayDates)); } // Get all days in the interval const days = eachDayOfInterval({ start: startDate, end: endDate, }); debug.timing('Processing %d days from %s to %s', days.length, start_date, end_date); // Categorize days into business, weekend, and holiday const categories = categorizeDays(days, allHolidayDates); // Adjust for weekend inclusion preference const adjustedCategories = adjustForWeekends(categories, excludeWeekends); const { businessDays, weekendDays, holidayCount } = adjustedCategories; // Log summary debug.business( 'Calculated business days: %d of %d total days (%d weekends, %d holidays)', businessDays, days.length, weekendDays, holidayCount ); const result: GetBusinessDaysResult = { total_days: days.length, business_days: businessDays, weekend_days: weekendDays, holiday_count: holidayCount, }; return result; }); }
- src/types/index.ts:95-110 (schema)TypeScript interfaces defining input parameters (GetBusinessDaysParams) and output structure (GetBusinessDaysResult) for the get_business_days tool.export interface GetBusinessDaysParams { start_date: string; end_date: string; exclude_weekends?: boolean; holidays?: string[]; timezone?: string; holiday_calendar?: string; include_observed?: boolean; custom_holidays?: string[]; } export interface GetBusinessDaysResult { total_days: number; business_days: number; weekend_days: number; holiday_count: number;
- src/index.ts:133-156 (registration)MCP tool registration in TOOL_DEFINITIONS array: defines name 'get_business_days', description, and inputSchema for the listTools endpoint.name: 'get_business_days', description: 'Calculate business days between dates', inputSchema: { type: 'object' as const, properties: { start_date: { type: 'string' as const, description: 'Start date' }, end_date: { type: 'string' as const, description: 'End date' }, exclude_weekends: { type: 'boolean' as const, description: 'Exclude weekends (default: true)', }, holidays: { type: 'array' as const, items: { type: 'string' as const }, description: 'Array of holiday dates', }, timezone: { type: 'string' as const, description: 'Timezone for calculation (default: system timezone)', }, }, required: ['start_date', 'end_date'], }, },
- src/index.ts:266-267 (registration)Mapping in TOOL_FUNCTIONS object that connects the 'get_business_days' tool name to the getBusinessDays handler function for execution.get_business_days: (params: unknown) => getBusinessDays(params as Parameters<typeof getBusinessDays>[0]),