calculate_business_hours
Calculate the number of business hours between two timestamps, accounting for specified business hours, timezones, holidays, and weekend exclusions.
Instructions
Calculate business hours between two times
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| business_hours | No | Business hours definition (default: 9 AM - 5 PM) | |
| end_time | Yes | End time | |
| holidays | No | Array of holiday dates | |
| include_weekends | No | Include weekends in calculation (default: false) | |
| start_time | Yes | Start time | |
| timezone | No | Timezone for calculation (default: system timezone) |
Implementation Reference
- Primary handler function executing the core business hours calculation logic, including input validation, caching, date parsing, holiday processing, per-day business time calculation, and result aggregation.export function calculateBusinessHours( params: CalculateBusinessHoursParams ): CalculateBusinessHoursResult { const { start_time, end_time, holidays = [], include_weekends = false } = params; // Log entry with parameters debug.business('calculateBusinessHours called with params: %O', { start_time, end_time, timezone: params.timezone, business_hours: params.business_hours ?? 'default', holidays_count: holidays.length, include_weekends, }); const config = getConfig(); const timezone = resolveTimezone(params.timezone, config.defaultTimezone); // Validate all input parameters validateBusinessHoursParams({ start_time, end_time, holidays, timezone, business_hours: params.business_hours, }); // Build cache key const cacheKey = buildBusinessHoursCacheKey({ start_time, end_time, timezone, business_hours: params.business_hours, holidays, include_weekends, }); // Use withCache wrapper for the calculation return withCache(cacheKey, CacheTTL.CALCULATIONS, () => { // Parse dates const startDate = parseDateWithTimezone(start_time, timezone, 'start_time'); const endDate = parseDateWithTimezone(end_time, timezone, 'end_time'); // Validate date range validateBusinessDateRange(startDate, endDate, start_time, end_time); // Log the calculation context debug.business( 'Business hours calculation: %s to %s in %s', formatInTimeZone(startDate, timezone, 'yyyy-MM-dd HH:mm'), formatInTimeZone(endDate, timezone, 'yyyy-MM-dd HH:mm'), timezone ); // Parse holiday dates const holidayDates = parseHolidayDates(holidays, timezone); if (holidayDates.length > 0) { debug.business('Holidays to exclude: %O', holidayDates); } // Generate date range to process const dateStrings = generateDateRange(startDate, endDate, timezone); // Process all days in the date range const { breakdown, totalMinutes } = processDateRange({ dateStrings, startDate, endDate, timezone, holidayDates, include_weekends, business_hours: params.business_hours, }); // Build and return the final result const result = buildBusinessHoursResult(breakdown, totalMinutes); // Log successful completion debug.business( 'calculateBusinessHours completed successfully: %d total hours', result.total_business_hours ); return result; }); }
- src/index.ts:202-229 (registration)Tool registration in TOOL_DEFINITIONS array, defining the tool name, description, and input schema for MCP server.name: 'calculate_business_hours', description: 'Calculate business hours between two times', inputSchema: { type: 'object' as const, properties: { start_time: { type: 'string' as const, description: 'Start time' }, end_time: { type: 'string' as const, description: 'End time' }, business_hours: { type: 'object' as const, description: 'Business hours definition (default: 9 AM - 5 PM)', }, timezone: { type: 'string' as const, description: 'Timezone for calculation (default: system timezone)', }, holidays: { type: 'array' as const, items: { type: 'string' as const }, description: 'Array of holiday dates', }, include_weekends: { type: 'boolean' as const, description: 'Include weekends in calculation (default: false)', }, }, required: ['start_time', 'end_time'], }, },
- src/index.ts:271-272 (registration)Tool function mapping in TOOL_FUNCTIONS object, linking the snake_case tool name to the camelCase handler implementation.calculate_business_hours: (params: unknown) => calculateBusinessHours(params as Parameters<typeof calculateBusinessHours>[0]),
- src/types/index.ts:141-171 (schema)TypeScript type definitions for CalculateBusinessHoursParams, CalculateBusinessHoursResult, BusinessHours, WeeklyBusinessHours, and DayBusinessHours used for input/output typing and validation.export interface BusinessHours { start: { hour: number; minute: number }; end: { hour: number; minute: number }; } export interface WeeklyBusinessHours { [dayOfWeek: number]: BusinessHours | null; // 0-6, Sunday=0, null=closed } export interface CalculateBusinessHoursParams { start_time: string; end_time: string; business_hours?: BusinessHours | WeeklyBusinessHours; timezone?: string; holidays?: string[]; include_weekends?: boolean; } export interface DayBusinessHours { date: string; day_of_week: string; business_minutes: number; is_weekend: boolean; is_holiday: boolean; } export interface CalculateBusinessHoursResult { total_business_minutes: number; total_business_hours: number; breakdown: DayBusinessHours[]; }
- Key helper function that iterates over date range, determines business hours per day, checks holidays and weekends, and aggregates total business minutes with day breakdown.function processDateRange(params: { dateStrings: string[]; startDate: Date; endDate: Date; timezone: string; holidayDates: Date[]; include_weekends: boolean; business_hours?: BusinessHours | WeeklyBusinessHours; }): { breakdown: DayBusinessHours[]; totalMinutes: number } { const { dateStrings, startDate, endDate, timezone, holidayDates, include_weekends, business_hours, } = params; const breakdown: DayBusinessHours[] = []; let totalBusinessMinutes = 0; for (const dayDateStr of dateStrings) { // Get day information const day = parseTimeInput(dayDateStr + 'T12:00:00', timezone).date; const dayOfWeek = parseInt(formatInTimeZone(day, timezone, 'c'), 10) - 1; const isWeekendDay = dayOfWeek === 0 || dayOfWeek === 6; // Get business hours for this day const dayBusinessHours = getBusinessHoursForDay(dayOfWeek, business_hours); // Process the single day const { dayResult, minutes } = processSingleBusinessDay({ dayDateStr, startDate, endDate, timezone, businessHours: dayBusinessHours, holidayDates, include_weekends, dayOfWeek, isWeekend: isWeekendDay, }); breakdown.push(dayResult); totalBusinessMinutes += minutes; } return { breakdown, totalMinutes: totalBusinessMinutes }; }