Improves date handling and event stacking
Enhances date validation and timezone handling using DateService, ensuring data integrity and consistency. Refactors event rendering and dragging to correctly handle date transformations. Adds a test plan for event stacking and z-index management. Fixes edge cases in navigation and date calculations for week/year boundaries and DST transitions.
This commit is contained in:
parent
a86a736340
commit
9bc082eed4
20 changed files with 1641 additions and 41 deletions
|
|
@ -101,6 +101,16 @@ export class DateService {
|
|||
public formatDate(date: Date): string {
|
||||
return format(date, 'yyyy-MM-dd');
|
||||
}
|
||||
|
||||
/**
|
||||
* Format date as "Month Year" (e.g., "January 2025")
|
||||
* @param date - Date to format
|
||||
* @param locale - Locale for month name (default: 'en-US')
|
||||
* @returns Formatted month and year
|
||||
*/
|
||||
public formatMonthYear(date: Date, locale: string = 'en-US'): string {
|
||||
return date.toLocaleDateString(locale, { month: 'long', year: 'numeric' });
|
||||
}
|
||||
|
||||
/**
|
||||
* Format date as ISO string (same as formatDate for compatibility)
|
||||
|
|
@ -413,6 +423,76 @@ export class DateService {
|
|||
public isValid(date: Date): boolean {
|
||||
return isValid(date);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate date range (start must be before or equal to end)
|
||||
* @param start - Start date
|
||||
* @param end - End date
|
||||
* @returns True if valid range
|
||||
*/
|
||||
public isValidRange(start: Date, end: Date): boolean {
|
||||
if (!this.isValid(start) || !this.isValid(end)) {
|
||||
return false;
|
||||
}
|
||||
return start.getTime() <= end.getTime();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if date is within reasonable bounds (1900-2100)
|
||||
* @param date - Date to check
|
||||
* @returns True if within bounds
|
||||
*/
|
||||
public isWithinBounds(date: Date): boolean {
|
||||
if (!this.isValid(date)) {
|
||||
return false;
|
||||
}
|
||||
const year = date.getFullYear();
|
||||
return year >= 1900 && year <= 2100;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate date with comprehensive checks
|
||||
* @param date - Date to validate
|
||||
* @param options - Validation options
|
||||
* @returns Validation result with error message
|
||||
*/
|
||||
public validateDate(
|
||||
date: Date,
|
||||
options: {
|
||||
requireFuture?: boolean;
|
||||
requirePast?: boolean;
|
||||
minDate?: Date;
|
||||
maxDate?: Date;
|
||||
} = {}
|
||||
): { valid: boolean; error?: string } {
|
||||
if (!this.isValid(date)) {
|
||||
return { valid: false, error: 'Invalid date' };
|
||||
}
|
||||
|
||||
if (!this.isWithinBounds(date)) {
|
||||
return { valid: false, error: 'Date out of bounds (1900-2100)' };
|
||||
}
|
||||
|
||||
const now = new Date();
|
||||
|
||||
if (options.requireFuture && date <= now) {
|
||||
return { valid: false, error: 'Date must be in the future' };
|
||||
}
|
||||
|
||||
if (options.requirePast && date >= now) {
|
||||
return { valid: false, error: 'Date must be in the past' };
|
||||
}
|
||||
|
||||
if (options.minDate && date < options.minDate) {
|
||||
return { valid: false, error: `Date must be after ${this.formatDate(options.minDate)}` };
|
||||
}
|
||||
|
||||
if (options.maxDate && date > options.maxDate) {
|
||||
return { valid: false, error: `Date must be before ${this.formatDate(options.maxDate)}` };
|
||||
}
|
||||
|
||||
return { valid: true };
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if event spans multiple days
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue