Refactors date calculations into DateCalculator
Centralizes date calculation logic into a dedicated DateCalculator class for improved maintainability and testability. Removes redundant date calculation methods from CalendarManager, ColumnRenderer, HeaderRenderer and NavigationRenderer, and utilizes the DateCalculator for these calculations. Updates components to use DateCalculator for consistent date handling, including week start determination, date formatting, and "is today" checks.
This commit is contained in:
parent
2f854b2c64
commit
18f7953db4
5 changed files with 233 additions and 124 deletions
194
src/utils/DateCalculator.ts
Normal file
194
src/utils/DateCalculator.ts
Normal file
|
|
@ -0,0 +1,194 @@
|
|||
/**
|
||||
* DateCalculator - Centralized date calculation logic for calendar
|
||||
* Handles all date computations with proper week start handling
|
||||
*/
|
||||
|
||||
import { CalendarConfig } from '../core/CalendarConfig';
|
||||
|
||||
export class DateCalculator {
|
||||
private config: CalendarConfig;
|
||||
|
||||
constructor(config: CalendarConfig) {
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get dates for work week based on week start and work days configuration
|
||||
* @param weekStart - The start date of the week (could be Sunday or Monday)
|
||||
* @returns Array of dates for the configured work days
|
||||
*/
|
||||
getWorkWeekDates(weekStart: Date): Date[] {
|
||||
const dates: Date[] = [];
|
||||
const workWeekSettings = this.config.getWorkWeekSettings();
|
||||
const dateSettings = this.config.getDateViewSettings();
|
||||
const firstDayOfWeek = dateSettings.firstDayOfWeek; // 0=Sunday, 1=Monday
|
||||
|
||||
// Get the actual start of the week based on configuration
|
||||
const actualWeekStart = this.getWeekStart(weekStart, firstDayOfWeek);
|
||||
|
||||
// Calculate dates for each work day
|
||||
workWeekSettings.workDays.forEach(dayOfWeek => {
|
||||
const date = new Date(actualWeekStart);
|
||||
|
||||
if (firstDayOfWeek === 1 && dayOfWeek === 0) {
|
||||
// For Monday-based weeks, Sunday is at the end (day 7)
|
||||
date.setDate(actualWeekStart.getDate() + 7);
|
||||
} else {
|
||||
// Normal calculation
|
||||
date.setDate(actualWeekStart.getDate() + dayOfWeek);
|
||||
}
|
||||
|
||||
dates.push(date);
|
||||
});
|
||||
|
||||
return dates;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the start of the week for a given date
|
||||
* @param date - Any date in the week
|
||||
* @param firstDayOfWeek - 0 for Sunday, 1 for Monday
|
||||
* @returns The start date of the week
|
||||
*/
|
||||
getWeekStart(date: Date, firstDayOfWeek: number = 1): Date {
|
||||
const weekStart = new Date(date);
|
||||
const currentDay = weekStart.getDay();
|
||||
|
||||
if (firstDayOfWeek === 1) {
|
||||
// Monday as first day
|
||||
const daysToSubtract = currentDay === 0 ? 6 : currentDay - 1;
|
||||
weekStart.setDate(weekStart.getDate() - daysToSubtract);
|
||||
} else {
|
||||
// Sunday as first day
|
||||
weekStart.setDate(weekStart.getDate() - currentDay);
|
||||
}
|
||||
|
||||
weekStart.setHours(0, 0, 0, 0);
|
||||
return weekStart;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the end of the week for a given date
|
||||
* @param date - Any date in the week
|
||||
* @param firstDayOfWeek - 0 for Sunday, 1 for Monday
|
||||
* @returns The end date of the week
|
||||
*/
|
||||
getWeekEnd(date: Date, firstDayOfWeek: number = 1): Date {
|
||||
const weekStart = this.getWeekStart(date, firstDayOfWeek);
|
||||
const weekEnd = new Date(weekStart);
|
||||
weekEnd.setDate(weekStart.getDate() + 6);
|
||||
weekEnd.setHours(23, 59, 59, 999);
|
||||
return weekEnd;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get week number for a date (ISO 8601)
|
||||
* @param date - The date to get week number for
|
||||
* @returns Week number (1-53)
|
||||
*/
|
||||
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);
|
||||
const yearStart = new Date(Date.UTC(d.getUTCFullYear(),0,1));
|
||||
return Math.ceil((((d.getTime() - yearStart.getTime()) / 86400000) + 1)/7);
|
||||
}
|
||||
|
||||
/**
|
||||
* Format a date range for display
|
||||
* @param start - Start date
|
||||
* @param end - End date
|
||||
* @returns Formatted date range string
|
||||
*/
|
||||
formatDateRange(start: Date, end: Date): string {
|
||||
const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
|
||||
|
||||
const startMonth = months[start.getMonth()];
|
||||
const endMonth = months[end.getMonth()];
|
||||
const startDay = start.getDate();
|
||||
const endDay = end.getDate();
|
||||
const startYear = start.getFullYear();
|
||||
const endYear = end.getFullYear();
|
||||
|
||||
if (startYear !== endYear) {
|
||||
return `${startMonth} ${startDay}, ${startYear} - ${endMonth} ${endDay}, ${endYear}`;
|
||||
} else if (startMonth === endMonth) {
|
||||
return `${startMonth} ${startDay} - ${endDay}, ${startYear}`;
|
||||
} else {
|
||||
return `${startMonth} ${startDay} - ${endMonth} ${endDay}, ${startYear}`;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Format a date to ISO date string (YYYY-MM-DD)
|
||||
* @param date - Date to format
|
||||
* @returns ISO date string
|
||||
*/
|
||||
formatISODate(date: Date): string {
|
||||
return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a date is today
|
||||
* @param date - Date to check
|
||||
* @returns True if the date is today
|
||||
*/
|
||||
isToday(date: Date): boolean {
|
||||
const today = new Date();
|
||||
return date.toDateString() === today.toDateString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add days to a date
|
||||
* @param date - Base date
|
||||
* @param days - Number of days to add (can be negative)
|
||||
* @returns New date
|
||||
*/
|
||||
addDays(date: Date, days: number): Date {
|
||||
const result = new Date(date);
|
||||
result.setDate(result.getDate() + days);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add weeks to a date
|
||||
* @param date - Base date
|
||||
* @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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all dates in a week
|
||||
* @param weekStart - Start of the week
|
||||
* @returns Array of 7 dates for the full week
|
||||
*/
|
||||
getFullWeekDates(weekStart: Date): Date[] {
|
||||
const dates: Date[] = [];
|
||||
for (let i = 0; i < 7; i++) {
|
||||
dates.push(this.addDays(weekStart, i));
|
||||
}
|
||||
return dates;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the day name for a date
|
||||
* @param date - Date to get day name for
|
||||
* @param format - 'short' or 'long'
|
||||
* @returns Day name
|
||||
*/
|
||||
getDayName(date: Date, format: 'short' | 'long' = 'short'): string {
|
||||
const days = {
|
||||
short: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
|
||||
long: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']
|
||||
};
|
||||
return days[format][date.getDay()];
|
||||
}
|
||||
}
|
||||
|
||||
// Create singleton instance with config
|
||||
export function createDateCalculator(config: CalendarConfig): DateCalculator {
|
||||
return new DateCalculator(config);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue