Skip to main content
Glama
pshempel

MCP Time Server Node

by pshempel
businessDayHelpers.ts3.62 kB
import { format, isWeekend } from 'date-fns'; import { ValidationError } from '../adapters/mcp-sdk'; import { debug } from './debug'; export interface DayCategories { businessDays: number; weekendDays: number; holidayCount: number; } /** * Validates a holiday calendar code * @param calendar - The calendar code to validate (e.g., 'US', 'UK') * @throws ValidationError if the calendar code is invalid */ export function validateHolidayCalendar(calendar: string): void { if (calendar.includes('\0') || calendar.includes('\x00')) { debug.error('Invalid holiday_calendar contains null bytes: %s', calendar); throw new ValidationError('Invalid holiday_calendar: contains null bytes', { holiday_calendar: calendar, }); } if (!/^[A-Z]{2,3}$/.test(calendar)) { debug.error('Invalid holiday_calendar format: %s', calendar); throw new ValidationError('Invalid holiday_calendar: must be a 2-3 letter country code', { holiday_calendar: calendar, }); } } /** * Validates that a date range doesn't exceed 100 years (DoS protection) * @param startDate - Start date * @param endDate - End date * @param start_date - Original start date string for error reporting * @param end_date - Original end date string for error reporting * @throws ValidationError if the date range exceeds 100 years */ export function validateDateRange( startDate: Date, endDate: Date, start_date: string, end_date: string ): void { const daysDifference = Math.abs(endDate.getTime() - startDate.getTime()) / (1000 * 60 * 60 * 24); if (daysDifference > 36525) { // Allow exactly 100 years (including leap years) debug.error('Date range too large: %d days (max 36500)', daysDifference); throw new ValidationError('Date range exceeds maximum limit of 100 years', { start_date, end_date, days: Math.floor(daysDifference), max_days: 36500, }); } } /** * Categorizes an array of days into business days, weekends, and holidays * @param days - Array of dates to categorize * @param allHolidayDates - Set of holiday date strings (toDateString() format) * @returns Object with counts for each category */ export function categorizeDays(days: Date[], allHolidayDates: Set<string>): DayCategories { let businessDays = 0; let weekendDays = 0; let holidayCount = 0; for (const day of days) { const isWeekendDay = isWeekend(day); const isHolidayDay = allHolidayDates.has(day.toDateString()); const dayStr = format(day, 'yyyy-MM-dd'); if (isWeekendDay) { weekendDays++; debug.trace(' %s: weekend', dayStr); } else if (isHolidayDay) { holidayCount++; debug.trace(' %s: holiday', dayStr); } else { businessDays++; debug.trace(' %s: business day', dayStr); } } return { businessDays, weekendDays, holidayCount, }; } /** * Adjusts business day count based on weekend inclusion preference * @param categories - Day categories from categorizeDays * @param excludeWeekends - Whether to exclude weekends from business days * @returns Adjusted day categories */ export function adjustForWeekends( categories: DayCategories, excludeWeekends: boolean ): DayCategories { if (!excludeWeekends) { debug.decision('Including weekends', { weekendDays: categories.weekendDays, businessDaysBefore: categories.businessDays, businessDaysAfter: categories.businessDays + categories.weekendDays, }); return { ...categories, businessDays: categories.businessDays + categories.weekendDays, }; } return categories; }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/pshempel/mcp-time-server-node'

If you have feedback or need assistance with the MCP directory API, please join our Discord server