From b8b44ddae8b291589f9f47988e91d08ee617ad4d Mon Sep 17 00:00:00 2001 From: Janus Knudsen Date: Wed, 3 Sep 2025 18:38:52 +0200 Subject: [PATCH] Refactors DateCalculator to be a static class This change refactors the DateCalculator class to be a static class. This removes the need to instantiate DateCalculator in multiple managers and renderers, simplifying dependency management and ensuring consistent date calculations across the application. The configuration is now initialized once at the application start. --- src/index.ts | 4 ++ src/managers/CalendarManager.ts | 7 +-- src/managers/NavigationManager.ts | 15 +++--- src/managers/WorkHoursManager.ts | 7 +-- src/renderers/ColumnRenderer.ts | 7 +-- src/renderers/EventRenderer.ts | 11 +++-- src/renderers/HeaderRenderer.ts | 11 +++-- src/renderers/NavigationRenderer.ts | 15 +++--- src/strategies/MonthViewStrategy.ts | 15 +++--- src/strategies/WeekViewStrategy.ts | 21 ++++---- src/utils/DateCalculator.ts | 77 ++++++++++++++++------------- 11 files changed, 107 insertions(+), 83 deletions(-) diff --git a/src/index.ts b/src/index.ts index 41871d9..d6d1b5b 100644 --- a/src/index.ts +++ b/src/index.ts @@ -3,6 +3,7 @@ import { eventBus } from './core/EventBus.js'; import { calendarConfig } from './core/CalendarConfig.js'; import { CalendarTypeFactory } from './factories/CalendarTypeFactory.js'; import { ManagerFactory } from './factories/ManagerFactory.js'; +import { DateCalculator } from './utils/DateCalculator.js'; /** * Initialize the calendar application with simple direct calls @@ -13,6 +14,9 @@ async function initializeCalendar(): Promise { // Use the singleton calendar configuration const config = calendarConfig; + // Initialize DateCalculator with config first + DateCalculator.initialize(config); + // Initialize the CalendarTypeFactory before creating managers CalendarTypeFactory.initialize(); diff --git a/src/managers/CalendarManager.ts b/src/managers/CalendarManager.ts index 999cc4c..0200175 100644 --- a/src/managers/CalendarManager.ts +++ b/src/managers/CalendarManager.ts @@ -41,7 +41,8 @@ export class CalendarManager { this.eventRenderer = eventRenderer; this.scrollManager = scrollManager; this.eventFilterManager = new EventFilterManager(); - this.dateCalculator = new DateCalculator(config); + DateCalculator.initialize(config); + this.dateCalculator = new DateCalculator(); this.setupEventListeners(); } @@ -434,10 +435,10 @@ export class CalendarManager { const lastDate = new Date(lastDateStr); // Calculate week number from first date - const weekNumber = this.dateCalculator.getWeekNumber(firstDate); + const weekNumber = DateCalculator.getWeekNumber(firstDate); // Format date range - const dateRange = this.dateCalculator.formatDateRange(firstDate, lastDate); + const dateRange = DateCalculator.formatDateRange(firstDate, lastDate); // Emit week info update this.eventBus.emit(CoreEvents.WEEK_CHANGED, { diff --git a/src/managers/NavigationManager.ts b/src/managers/NavigationManager.ts index 9e0784c..90e8cc2 100644 --- a/src/managers/NavigationManager.ts +++ b/src/managers/NavigationManager.ts @@ -23,9 +23,10 @@ export class NavigationManager { constructor(eventBus: IEventBus, eventRenderer: EventRenderingService) { this.eventBus = eventBus; - this.dateCalculator = new DateCalculator(calendarConfig); + DateCalculator.initialize(calendarConfig); + this.dateCalculator = new DateCalculator(); this.navigationRenderer = new NavigationRenderer(eventBus, calendarConfig, eventRenderer); - this.currentWeek = this.dateCalculator.getISOWeekStart(new Date()); + this.currentWeek = DateCalculator.getISOWeekStart(new Date()); this.targetWeek = new Date(this.currentWeek); this.init(); } @@ -135,7 +136,7 @@ export class NavigationManager { private navigateToToday(): void { const today = new Date(); - const todayWeekStart = this.dateCalculator.getISOWeekStart(today); + const todayWeekStart = DateCalculator.getISOWeekStart(today); // Reset to today this.targetWeek = new Date(todayWeekStart); @@ -153,7 +154,7 @@ export class NavigationManager { } private navigateToDate(date: Date): void { - const weekStart = this.dateCalculator.getISOWeekStart(date); + const weekStart = DateCalculator.getISOWeekStart(date); this.targetWeek = new Date(weekStart); const currentTime = this.currentWeek.getTime(); @@ -247,9 +248,9 @@ export class NavigationManager { } private updateWeekInfo(): void { - const weekNumber = this.dateCalculator.getWeekNumber(this.currentWeek); - const weekEnd = this.dateCalculator.addDays(this.currentWeek, 6); - const dateRange = this.dateCalculator.formatDateRange(this.currentWeek, weekEnd); + const weekNumber = DateCalculator.getWeekNumber(this.currentWeek); + const weekEnd = DateCalculator.addDays(this.currentWeek, 6); + const dateRange = DateCalculator.formatDateRange(this.currentWeek, weekEnd); // Notify other managers about week info update - DOM manipulation should happen via events this.eventBus.emit(CoreEvents.WEEK_CHANGED, { diff --git a/src/managers/WorkHoursManager.ts b/src/managers/WorkHoursManager.ts index 1aa8288..e379a67 100644 --- a/src/managers/WorkHoursManager.ts +++ b/src/managers/WorkHoursManager.ts @@ -39,7 +39,8 @@ export class WorkHoursManager { constructor(config: CalendarConfig) { this.config = config; - this.dateCalculator = new DateCalculator(config); + DateCalculator.initialize(config); + this.dateCalculator = new DateCalculator(); // Default work schedule - will be loaded from JSON later this.workSchedule = { @@ -64,7 +65,7 @@ export class WorkHoursManager { * Get work hours for a specific date */ getWorkHoursForDate(date: Date): DayWorkHours | 'off' { - const dateString = this.dateCalculator.formatISODate(date); + const dateString = DateCalculator.formatISODate(date); // Check for date-specific override first if (this.workSchedule.dateOverrides[dateString]) { @@ -83,7 +84,7 @@ export class WorkHoursManager { const workHoursMap = new Map(); dates.forEach(date => { - const dateString = this.dateCalculator.formatISODate(date); + const dateString = DateCalculator.formatISODate(date); const workHours = this.getWorkHoursForDate(date); workHoursMap.set(dateString, workHours); }); diff --git a/src/renderers/ColumnRenderer.ts b/src/renderers/ColumnRenderer.ts index 4317736..f9fae00 100644 --- a/src/renderers/ColumnRenderer.ts +++ b/src/renderers/ColumnRenderer.ts @@ -32,17 +32,18 @@ export class DateColumnRenderer implements ColumnRenderer { const { currentWeek, config } = context; // Initialize date calculator and work hours manager - this.dateCalculator = new DateCalculator(config); + DateCalculator.initialize(config); + this.dateCalculator = new DateCalculator(); this.workHoursManager = new WorkHoursManager(config); - const dates = this.dateCalculator.getWorkWeekDates(currentWeek); + const dates = DateCalculator.getWorkWeekDates(currentWeek); const dateSettings = config.getDateViewSettings(); const daysToShow = dates.slice(0, dateSettings.weekDays); daysToShow.forEach((date) => { const column = document.createElement('swp-day-column'); - (column as any).dataset.date = this.dateCalculator.formatISODate(date); + (column as any).dataset.date = DateCalculator.formatISODate(date); // Apply work hours styling this.applyWorkHoursToColumn(column, date); diff --git a/src/renderers/EventRenderer.ts b/src/renderers/EventRenderer.ts index 2c00be1..aeac023 100644 --- a/src/renderers/EventRenderer.ts +++ b/src/renderers/EventRenderer.ts @@ -28,7 +28,10 @@ export abstract class BaseEventRenderer implements EventRendererStrategy { constructor(config: CalendarConfig, dateCalculator?: DateCalculator) { this.config = config; - this.dateCalculator = dateCalculator || new DateCalculator(config); + if (!dateCalculator) { + DateCalculator.initialize(config); + } + this.dateCalculator = dateCalculator || new DateCalculator(); } /** @@ -628,7 +631,7 @@ export abstract class BaseEventRenderer implements EventRendererStrategy { private calculateEventGridSpan(event: CalendarEvent, dateToColumnMap: Map): { startColumn: number, columnSpan: number } { const startDate = new Date(event.start); const endDate = new Date(event.end); - const startDateKey = this.dateCalculator.formatISODate(startDate); + const startDateKey = DateCalculator.formatISODate(startDate); const startColumn = dateToColumnMap.get(startDateKey); if (!startColumn) { @@ -641,7 +644,7 @@ export abstract class BaseEventRenderer implements EventRendererStrategy { while (currentDate <= endDate) { currentDate.setDate(currentDate.getDate() + 1); - const dateKey = this.dateCalculator.formatISODate(currentDate); + const dateKey = DateCalculator.formatISODate(currentDate); const col = dateToColumnMap.get(dateKey); if (col) { endColumn = col; @@ -696,7 +699,7 @@ export class DateEventRenderer extends BaseEventRenderer { const columnEvents = events.filter(event => { const eventDate = new Date(event.start); - const eventDateStr = this.dateCalculator.formatISODate(eventDate); + const eventDateStr = DateCalculator.formatISODate(eventDate); const matches = eventDateStr === columnDate; diff --git a/src/renderers/HeaderRenderer.ts b/src/renderers/HeaderRenderer.ts index 9f1eaa2..54dc452 100644 --- a/src/renderers/HeaderRenderer.ts +++ b/src/renderers/HeaderRenderer.ts @@ -256,25 +256,26 @@ export class DateHeaderRenderer extends BaseHeaderRenderer { const { currentWeek, config } = context; // Initialize date calculator with config - this.dateCalculator = new DateCalculator(config); + DateCalculator.initialize(config); + this.dateCalculator = new DateCalculator(); - const dates = this.dateCalculator.getWorkWeekDates(currentWeek); + const dates = DateCalculator.getWorkWeekDates(currentWeek); const weekDays = config.getDateViewSettings().weekDays; const daysToShow = dates.slice(0, weekDays); daysToShow.forEach((date, index) => { const header = document.createElement('swp-day-header'); - if (this.dateCalculator.isToday(date)) { + if (DateCalculator.isToday(date)) { (header as any).dataset.today = 'true'; } - const dayName = this.dateCalculator.getDayName(date, 'short'); + const dayName = DateCalculator.getDayName(date, 'short'); header.innerHTML = ` ${dayName} ${date.getDate()} `; - (header as any).dataset.date = this.dateCalculator.formatISODate(date); + (header as any).dataset.date = DateCalculator.formatISODate(date); calendarHeader.appendChild(header); }); diff --git a/src/renderers/NavigationRenderer.ts b/src/renderers/NavigationRenderer.ts index 60efdfd..19f6edb 100644 --- a/src/renderers/NavigationRenderer.ts +++ b/src/renderers/NavigationRenderer.ts @@ -24,7 +24,8 @@ export class NavigationRenderer { this.eventBus = eventBus; this.config = config; this.eventRenderer = eventRenderer; - this.dateCalculator = new DateCalculator(config); + DateCalculator.initialize(config); + this.dateCalculator = new DateCalculator(); this.setupEventListeners(); } @@ -127,7 +128,7 @@ export class NavigationRenderer { * Render a complete container with content and events */ public renderContainer(parentContainer: HTMLElement, weekStart: Date): HTMLElement { - const weekEnd = this.dateCalculator.addDays(weekStart, 6); + const weekEnd = DateCalculator.addDays(weekStart, 6); // Create new grid container @@ -179,22 +180,22 @@ export class NavigationRenderer { dayColumns.innerHTML = ''; // Get dates using DateCalculator - const dates = this.dateCalculator.getWorkWeekDates(weekStart); + const dates = DateCalculator.getWorkWeekDates(weekStart); // Render headers for target week dates.forEach((date, i) => { const headerElement = document.createElement('swp-day-header'); - if (this.dateCalculator.isToday(date)) { + if (DateCalculator.isToday(date)) { headerElement.dataset.today = 'true'; } - const dayName = this.dateCalculator.getDayName(date, 'short'); + const dayName = DateCalculator.getDayName(date, 'short'); headerElement.innerHTML = ` ${dayName} ${date.getDate()} `; - headerElement.dataset.date = this.dateCalculator.formatISODate(date); + headerElement.dataset.date = DateCalculator.formatISODate(date); header.appendChild(headerElement); }); @@ -209,7 +210,7 @@ export class NavigationRenderer { // Render day columns for target week dates.forEach(date => { const column = document.createElement('swp-day-column'); - column.dataset.date = this.dateCalculator.formatISODate(date); + column.dataset.date = DateCalculator.formatISODate(date); const eventsLayer = document.createElement('swp-events-layer'); column.appendChild(eventsLayer); diff --git a/src/strategies/MonthViewStrategy.ts b/src/strategies/MonthViewStrategy.ts index 5c8b71c..c73642f 100644 --- a/src/strategies/MonthViewStrategy.ts +++ b/src/strategies/MonthViewStrategy.ts @@ -11,7 +11,8 @@ export class MonthViewStrategy implements ViewStrategy { private dateCalculator: DateCalculator; constructor() { - this.dateCalculator = new DateCalculator(calendarConfig); + DateCalculator.initialize(calendarConfig); + this.dateCalculator = new DateCalculator(); } getLayoutConfig(): ViewLayoutConfig { @@ -72,7 +73,7 @@ export class MonthViewStrategy implements ViewStrategy { dates.forEach(date => { const cell = document.createElement('div'); cell.className = 'month-day-cell'; - cell.dataset.date = this.dateCalculator.formatISODate(date); + cell.dataset.date = DateCalculator.formatISODate(date); cell.style.border = '1px solid #e0e0e0'; cell.style.minHeight = '100px'; cell.style.padding = '4px'; @@ -86,7 +87,7 @@ export class MonthViewStrategy implements ViewStrategy { dayNumber.style.marginBottom = '4px'; // Check if today - if (this.dateCalculator.isToday(date)) { + if (DateCalculator.isToday(date)) { dayNumber.style.color = '#1976d2'; cell.style.backgroundColor = '#f5f5f5'; } @@ -101,12 +102,12 @@ export class MonthViewStrategy implements ViewStrategy { const firstOfMonth = new Date(monthDate.getFullYear(), monthDate.getMonth(), 1); // Get Monday of the week containing first day - const startDate = this.dateCalculator.getISOWeekStart(firstOfMonth); + const startDate = DateCalculator.getISOWeekStart(firstOfMonth); // Generate 42 days (6 weeks) const dates: Date[] = []; for (let i = 0; i < 42; i++) { - dates.push(this.dateCalculator.addDays(startDate, i)); + dates.push(DateCalculator.addDays(startDate, i)); } return dates; @@ -141,10 +142,10 @@ export class MonthViewStrategy implements ViewStrategy { const firstOfMonth = new Date(baseDate.getFullYear(), baseDate.getMonth(), 1); // Get Monday of the week containing first day - const startDate = this.dateCalculator.getISOWeekStart(firstOfMonth); + const startDate = DateCalculator.getISOWeekStart(firstOfMonth); // End date is 41 days after start (42 total days) - const endDate = this.dateCalculator.addDays(startDate, 41); + const endDate = DateCalculator.addDays(startDate, 41); return { startDate, diff --git a/src/strategies/WeekViewStrategy.ts b/src/strategies/WeekViewStrategy.ts index 6ac9957..ce22e28 100644 --- a/src/strategies/WeekViewStrategy.ts +++ b/src/strategies/WeekViewStrategy.ts @@ -15,7 +15,8 @@ export class WeekViewStrategy implements ViewStrategy { private styleManager: GridStyleManager; constructor() { - this.dateCalculator = new DateCalculator(calendarConfig); + DateCalculator.initialize(calendarConfig); + this.dateCalculator = new DateCalculator(); this.gridRenderer = new GridRenderer(calendarConfig); this.styleManager = new GridStyleManager(calendarConfig); } @@ -42,28 +43,28 @@ export class WeekViewStrategy implements ViewStrategy { } getNextPeriod(currentDate: Date): Date { - return this.dateCalculator.addWeeks(currentDate, 1); + return DateCalculator.addWeeks(currentDate, 1); } getPreviousPeriod(currentDate: Date): Date { - return this.dateCalculator.addWeeks(currentDate, -1); + return DateCalculator.addWeeks(currentDate, -1); } getPeriodLabel(date: Date): string { - const weekStart = this.dateCalculator.getISOWeekStart(date); - const weekEnd = this.dateCalculator.addDays(weekStart, 6); - const weekNumber = this.dateCalculator.getWeekNumber(date); + const weekStart = DateCalculator.getISOWeekStart(date); + const weekEnd = DateCalculator.addDays(weekStart, 6); + const weekNumber = DateCalculator.getWeekNumber(date); - return `Week ${weekNumber}: ${this.dateCalculator.formatDateRange(weekStart, weekEnd)}`; + return `Week ${weekNumber}: ${DateCalculator.formatDateRange(weekStart, weekEnd)}`; } getDisplayDates(baseDate: Date): Date[] { - return this.dateCalculator.getWorkWeekDates(baseDate); + return DateCalculator.getWorkWeekDates(baseDate); } getPeriodRange(baseDate: Date): { startDate: Date; endDate: Date } { - const weekStart = this.dateCalculator.getISOWeekStart(baseDate); - const weekEnd = this.dateCalculator.addDays(weekStart, 6); + const weekStart = DateCalculator.getISOWeekStart(baseDate); + const weekEnd = DateCalculator.addDays(weekStart, 6); return { startDate: weekStart, diff --git a/src/utils/DateCalculator.ts b/src/utils/DateCalculator.ts index 26e061a..2b51f1d 100644 --- a/src/utils/DateCalculator.ts +++ b/src/utils/DateCalculator.ts @@ -6,10 +6,14 @@ import { CalendarConfig } from '../core/CalendarConfig'; export class DateCalculator { - private config: CalendarConfig; + private static config: CalendarConfig; - constructor(config: CalendarConfig) { - this.config = config; + /** + * Initialize DateCalculator with configuration + * @param config - Calendar configuration + */ + static initialize(config: CalendarConfig): void { + DateCalculator.config = config; } /** @@ -18,7 +22,7 @@ export class DateCalculator { * @param methodName - Name of calling method for error messages * @throws Error if date is invalid */ - private validateDate(date: Date, methodName: string): void { + private static validateDate(date: Date, methodName: string): void { if (!date || !(date instanceof Date) || isNaN(date.getTime())) { throw new Error(`${methodName}: Invalid date provided - ${date}`); } @@ -29,14 +33,14 @@ export class DateCalculator { * @param weekStart - Any date in the week * @returns Array of dates for the configured work days */ - getWorkWeekDates(weekStart: Date): Date[] { - this.validateDate(weekStart, 'getWorkWeekDates'); + static getWorkWeekDates(weekStart: Date): Date[] { + DateCalculator.validateDate(weekStart, 'getWorkWeekDates'); const dates: Date[] = []; - const workWeekSettings = this.config.getWorkWeekSettings(); + const workWeekSettings = DateCalculator.config.getWorkWeekSettings(); // Always use ISO week start (Monday) - const mondayOfWeek = this.getISOWeekStart(weekStart); + const mondayOfWeek = DateCalculator.getISOWeekStart(weekStart); // Calculate dates for each work day using ISO numbering workWeekSettings.workDays.forEach(isoDay => { @@ -55,8 +59,8 @@ export class DateCalculator { * @param date - Any date in the week * @returns The Monday of the ISO week */ - getISOWeekStart(date: Date): Date { - this.validateDate(date, 'getISOWeekStart'); + static getISOWeekStart(date: Date): Date { + DateCalculator.validateDate(date, 'getISOWeekStart'); const monday = new Date(date); const currentDay = monday.getDay(); @@ -72,10 +76,10 @@ export class DateCalculator { * @param date - Any date in the week * @returns The end date of the ISO week (Sunday) */ - getWeekEnd(date: Date): Date { - this.validateDate(date, 'getWeekEnd'); + static getWeekEnd(date: Date): Date { + DateCalculator.validateDate(date, 'getWeekEnd'); - const weekStart = this.getISOWeekStart(date); + const weekStart = DateCalculator.getISOWeekStart(date); const weekEnd = new Date(weekStart); weekEnd.setDate(weekStart.getDate() + 6); weekEnd.setHours(23, 59, 59, 999); @@ -87,7 +91,7 @@ export class DateCalculator { * @param date - The date to get week number for * @returns Week number (1-53) */ - getWeekNumber(date: Date): number { + static getWeekNumber(date: Date): number { const d = new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate())); const dayNum = d.getUTCDay() || 7; d.setUTCDate(d.getUTCDate() + 4 - dayNum); @@ -102,7 +106,7 @@ export class DateCalculator { * @param options - Formatting options * @returns Formatted date range string */ - formatDateRange( + static formatDateRange( start: Date, end: Date, options: { @@ -137,7 +141,7 @@ export class DateCalculator { * @param date - Date to format * @returns ISO date string */ - formatISODate(date: Date): string { + static formatISODate(date: Date): string { return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}`; } @@ -146,7 +150,7 @@ export class DateCalculator { * @param date - Date to check * @returns True if the date is today */ - isToday(date: Date): boolean { + static isToday(date: Date): boolean { const today = new Date(); return date.toDateString() === today.toDateString(); } @@ -157,7 +161,7 @@ export class DateCalculator { * @param days - Number of days to add (can be negative) * @returns New date */ - addDays(date: Date, days: number): Date { + static addDays(date: Date, days: number): Date { const result = new Date(date); result.setDate(result.getDate() + days); return result; @@ -169,8 +173,8 @@ export class DateCalculator { * @param weeks - Number of weeks to add (can be negative) * @returns New date */ - addWeeks(date: Date, weeks: number): Date { - return this.addDays(date, weeks * 7); + static addWeeks(date: Date, weeks: number): Date { + return DateCalculator.addDays(date, weeks * 7); } /** @@ -178,10 +182,10 @@ export class DateCalculator { * @param weekStart - Start of the week * @returns Array of 7 dates for the full week */ - getFullWeekDates(weekStart: Date): Date[] { + static getFullWeekDates(weekStart: Date): Date[] { const dates: Date[] = []; for (let i = 0; i < 7; i++) { - dates.push(this.addDays(weekStart, i)); + dates.push(DateCalculator.addDays(weekStart, i)); } return dates; } @@ -192,7 +196,7 @@ export class DateCalculator { * @param format - 'short' or 'long' * @returns Day name */ - getDayName(date: Date, format: 'short' | 'long' = 'short'): string { + static getDayName(date: Date, format: 'short' | 'long' = 'short'): string { const formatter = new Intl.DateTimeFormat('en-US', { weekday: format }); @@ -204,7 +208,7 @@ export class DateCalculator { * @param date - Date to format * @returns Time string */ - formatTime(date: Date): string { + static formatTime(date: Date): string { return `${String(date.getHours()).padStart(2, '0')}:${String(date.getMinutes()).padStart(2, '0')}`; } @@ -213,7 +217,7 @@ export class DateCalculator { * @param date - Date to format * @returns 12-hour time string */ - formatTime12(date: Date): string { + static formatTime12(date: Date): string { const hours = date.getHours(); const minutes = date.getMinutes(); const period = hours >= 12 ? 'PM' : 'AM'; @@ -227,7 +231,7 @@ export class DateCalculator { * @param minutes - Minutes since midnight * @returns Time string */ - minutesToTime(minutes: number): string { + static minutesToTime(minutes: number): string { const hours = Math.floor(minutes / 60); const mins = minutes % 60; const period = hours >= 12 ? 'PM' : 'AM'; @@ -241,7 +245,7 @@ export class DateCalculator { * @param timeStr - Time string * @returns Minutes since midnight */ - timeToMinutes(timeStr: string): number { + static timeToMinutes(timeStr: string): number { const [time] = timeStr.split('T').pop()!.split('.'); const [hours, minutes] = time.split(':').map(Number); return hours * 60 + minutes; @@ -252,7 +256,7 @@ export class DateCalculator { * @param date - Date or ISO string * @returns Minutes since midnight */ - getMinutesSinceMidnight(date: Date | string): number { + static getMinutesSinceMidnight(date: Date | string): number { const d = typeof date === 'string' ? new Date(date) : date; return d.getHours() * 60 + d.getMinutes(); } @@ -263,7 +267,7 @@ export class DateCalculator { * @param end - End date or ISO string * @returns Duration in minutes */ - getDurationMinutes(start: Date | string, end: Date | string): number { + static getDurationMinutes(start: Date | string, end: Date | string): number { const startDate = typeof start === 'string' ? new Date(start) : start; const endDate = typeof end === 'string' ? new Date(end) : end; return Math.floor((endDate.getTime() - startDate.getTime()) / 60000); @@ -275,7 +279,7 @@ export class DateCalculator { * @param date2 - Second date * @returns True if same day */ - isSameDay(date1: Date, date2: Date): boolean { + static isSameDay(date1: Date, date2: Date): boolean { return date1.toDateString() === date2.toDateString(); } @@ -285,15 +289,20 @@ export class DateCalculator { * @param end - End date or ISO string * @returns True if spans multiple days */ - isMultiDay(start: Date | string, end: Date | string): boolean { + static isMultiDay(start: Date | string, end: Date | string): boolean { const startDate = typeof start === 'string' ? new Date(start) : start; const endDate = typeof end === 'string' ? new Date(end) : end; - return !this.isSameDay(startDate, endDate); + return !DateCalculator.isSameDay(startDate, endDate); } + // Legacy constructor for backward compatibility + constructor() { + // Empty constructor - all methods are now static + } } -// Create singleton instance with config +// Legacy factory function - deprecated, use static methods instead export function createDateCalculator(config: CalendarConfig): DateCalculator { - return new DateCalculator(config); + DateCalculator.initialize(config); + return new DateCalculator(); } \ No newline at end of file