Refactors date handling to use DateService

Standardizes date manipulation across the application by leveraging the DateService.
This change improves consistency and reduces code duplication by removing redundant date calculations.
This commit is contained in:
Janus C. H. Knudsen 2025-10-03 20:59:52 +02:00
parent 6bbf2d8adb
commit a86a736340
6 changed files with 69 additions and 77 deletions

View file

@ -156,7 +156,7 @@ export class GridManager {
nextDate = this.dateService.addWeeks(this.currentDate, 1); nextDate = this.dateService.addWeeks(this.currentDate, 1);
break; break;
case 'month': case 'month':
nextDate = this.addMonths(this.currentDate, 1); nextDate = this.dateService.addMonths(this.currentDate, 1);
break; break;
case 'day': case 'day':
nextDate = this.dateService.addDays(this.currentDate, 1); nextDate = this.dateService.addDays(this.currentDate, 1);
@ -187,7 +187,7 @@ export class GridManager {
prevDate = this.dateService.addWeeks(this.currentDate, -1); prevDate = this.dateService.addWeeks(this.currentDate, -1);
break; break;
case 'month': case 'month':
prevDate = this.addMonths(this.currentDate, -1); prevDate = this.dateService.addMonths(this.currentDate, -1);
break; break;
case 'day': case 'day':
prevDate = this.dateService.addDays(this.currentDate, -1); prevDate = this.dateService.addDays(this.currentDate, -1);
@ -299,33 +299,22 @@ export class GridManager {
} }
} }
/**
* Helper method to add months to a date
*/
private addMonths(date: Date, months: number): Date {
const result = new Date(date);
result.setMonth(result.getMonth() + months);
return result;
}
/** /**
* Helper method to get month start * Helper method to get month start
*/ */
private getMonthStart(date: Date): Date { private getMonthStart(date: Date): Date {
const result = new Date(date); const year = date.getFullYear();
result.setDate(1); const month = date.getMonth();
result.setHours(0, 0, 0, 0); return this.dateService.startOfDay(new Date(year, month, 1));
return result;
} }
/** /**
* Helper method to get month end * Helper method to get month end
*/ */
private getMonthEnd(date: Date): Date { private getMonthEnd(date: Date): Date {
const result = new Date(date); const nextMonth = this.dateService.addMonths(date, 1);
result.setMonth(result.getMonth() + 1, 0); const firstOfNextMonth = this.getMonthStart(nextMonth);
result.setHours(23, 59, 59, 999); return this.dateService.endOfDay(this.dateService.addDays(firstOfNextMonth, -1));
return result;
} }
/** /**
@ -336,8 +325,10 @@ export class GridManager {
const monthStart = this.getMonthStart(date); const monthStart = this.getMonthStart(date);
const monthEnd = this.getMonthEnd(date); const monthEnd = this.getMonthEnd(date);
for (let d = new Date(monthStart); d <= monthEnd; d.setDate(d.getDate() + 1)) { const totalDays = Math.ceil((monthEnd.getTime() - monthStart.getTime()) / (1000 * 60 * 60 * 24)) + 1;
dates.push(new Date(d));
for (let i = 0; i < totalDays; i++) {
dates.push(this.dateService.addDays(monthStart, i));
} }
return dates; return dates;

View file

@ -153,14 +153,14 @@ export class NavigationManager {
} }
private navigateToPreviousWeek(): void { private navigateToPreviousWeek(): void {
this.targetWeek.setDate(this.targetWeek.getDate() - 7); this.targetWeek = this.dateService.addWeeks(this.targetWeek, -1);
const weekToShow = new Date(this.targetWeek); const weekToShow = new Date(this.targetWeek);
this.animationQueue++; this.animationQueue++;
this.animateTransition('prev', weekToShow); this.animateTransition('prev', weekToShow);
} }
private navigateToNextWeek(): void { private navigateToNextWeek(): void {
this.targetWeek.setDate(this.targetWeek.getDate() + 7); this.targetWeek = this.dateService.addWeeks(this.targetWeek, 1);
const weekToShow = new Date(this.targetWeek); const weekToShow = new Date(this.targetWeek);
this.animationQueue++; this.animationQueue++;
this.animateTransition('next', weekToShow); this.animateTransition('next', weekToShow);

View file

@ -11,7 +11,7 @@ import { DragOffset, StackLinkData } from '../types/DragDropTypes';
import { ColumnBounds } from '../utils/ColumnDetectionUtils'; import { ColumnBounds } from '../utils/ColumnDetectionUtils';
import { DragColumnChangeEventPayload, DragMoveEventPayload, DragStartEventPayload } from '../types/EventTypes'; import { DragColumnChangeEventPayload, DragMoveEventPayload, DragStartEventPayload } from '../types/EventTypes';
import { DateService } from '../utils/DateService'; import { DateService } from '../utils/DateService';
import { format, setHours, setMinutes, setSeconds, addDays } from 'date-fns'; import { format } from 'date-fns';
/** /**
* Interface for event rendering strategies * Interface for event rendering strategies
@ -164,40 +164,25 @@ export class DateEventRenderer implements EventRendererStrategy {
* Update data-start and data-end attributes with ISO timestamps * Update data-start and data-end attributes with ISO timestamps
*/ */
private updateDateTimeAttributes(element: HTMLElement, columnDate: Date, startMinutes: number, endMinutes: number): void { private updateDateTimeAttributes(element: HTMLElement, columnDate: Date, startMinutes: number, endMinutes: number): void {
const startDate = this.createDateWithMinutes(columnDate, startMinutes); const startDate = this.dateService.createDateAtTime(columnDate, startMinutes);
let endDate = this.createDateWithMinutes(columnDate, endMinutes); let endDate = this.dateService.createDateAtTime(columnDate, endMinutes);
// Handle cross-midnight events // Handle cross-midnight events
if (endMinutes >= 1440) { if (endMinutes >= 1440) {
const extraDays = Math.floor(endMinutes / 1440); const extraDays = Math.floor(endMinutes / 1440);
endDate = addDays(endDate, extraDays); endDate = this.dateService.addDays(endDate, extraDays);
} }
element.dataset.start = startDate.toISOString(); element.dataset.start = startDate.toISOString();
element.dataset.end = endDate.toISOString(); element.dataset.end = endDate.toISOString();
} }
/**
* Create a date with specific minutes since midnight
*/
private createDateWithMinutes(baseDate: Date, totalMinutes: number): Date {
const hours = Math.floor(totalMinutes / 60);
const minutes = totalMinutes % 60;
return setSeconds(setMinutes(setHours(baseDate, hours), minutes), 0);
}
/** /**
* Format minutes since midnight to time string * Format minutes since midnight to time string
*/ */
private formatTimeFromMinutes(totalMinutes: number): string { private formatTimeFromMinutes(totalMinutes: number): string {
const hours = Math.floor(totalMinutes / 60); return this.dateService.minutesToTime(totalMinutes);
const minutes = totalMinutes % 60;
const date = new Date();
date.setHours(hours, minutes, 0, 0);
return format(date, 'HH:mm');
} }
/** /**

View file

@ -98,8 +98,10 @@ export class MonthViewStrategy implements ViewStrategy {
} }
private getMonthDates(monthDate: Date): Date[] { private getMonthDates(monthDate: Date): Date[] {
// Get first day of month // Get first day of month using DateService
const firstOfMonth = new Date(monthDate.getFullYear(), monthDate.getMonth(), 1); const year = monthDate.getFullYear();
const month = monthDate.getMonth();
const firstOfMonth = this.dateService.startOfDay(new Date(year, month, 1));
// Get Monday of the week containing first day // Get Monday of the week containing first day
const weekBounds = this.dateService.getWeekBounds(firstOfMonth); const weekBounds = this.dateService.getWeekBounds(firstOfMonth);
@ -120,11 +122,17 @@ export class MonthViewStrategy implements ViewStrategy {
} }
getNextPeriod(currentDate: Date): Date { getNextPeriod(currentDate: Date): Date {
return new Date(currentDate.getFullYear(), currentDate.getMonth() + 1, 1); const nextMonth = this.dateService.addMonths(currentDate, 1);
const year = nextMonth.getFullYear();
const month = nextMonth.getMonth();
return this.dateService.startOfDay(new Date(year, month, 1));
} }
getPreviousPeriod(currentDate: Date): Date { getPreviousPeriod(currentDate: Date): Date {
return new Date(currentDate.getFullYear(), currentDate.getMonth() - 1, 1); const prevMonth = this.dateService.addMonths(currentDate, -1);
const year = prevMonth.getFullYear();
const month = prevMonth.getMonth();
return this.dateService.startOfDay(new Date(year, month, 1));
} }
getPeriodLabel(date: Date): string { getPeriodLabel(date: Date): string {
@ -140,7 +148,9 @@ export class MonthViewStrategy implements ViewStrategy {
getPeriodRange(baseDate: Date): { startDate: Date; endDate: Date } { getPeriodRange(baseDate: Date): { startDate: Date; endDate: Date } {
// Month view shows events for the entire month grid (including partial weeks) // Month view shows events for the entire month grid (including partial weeks)
const firstOfMonth = new Date(baseDate.getFullYear(), baseDate.getMonth(), 1); const year = baseDate.getFullYear();
const month = baseDate.getMonth();
const firstOfMonth = this.dateService.startOfDay(new Date(year, month, 1));
// Get Monday of the week containing first day // Get Monday of the week containing first day
const weekBounds = this.dateService.getWeekBounds(firstOfMonth); const weekBounds = this.dateService.getWeekBounds(firstOfMonth);

View file

@ -20,6 +20,7 @@ import {
startOfWeek, startOfWeek,
endOfWeek, endOfWeek,
addWeeks, addWeeks,
addMonths,
isSameDay, isSameDay,
getISOWeek getISOWeek
} from 'date-fns'; } from 'date-fns';
@ -258,6 +259,16 @@ export class DateService {
return addWeeks(date, weeks); return addWeeks(date, weeks);
} }
/**
* Add months to a date
* @param date - Base date
* @param months - Number of months to add (can be negative)
* @returns New date
*/
public addMonths(date: Date, months: number): Date {
return addMonths(date, months);
}
/** /**
* Get ISO week number (1-53) * Get ISO week number (1-53)
* @param date - Date to get week number for * @param date - Date to get week number for

View file

@ -226,12 +226,7 @@ export class PositionUtils {
*/ */
public static timeStringToIso(timeString: string, date: Date = new Date()): string { public static timeStringToIso(timeString: string, date: Date = new Date()): string {
const totalMinutes = PositionUtils.dateService.timeToMinutes(timeString); const totalMinutes = PositionUtils.dateService.timeToMinutes(timeString);
const hours = Math.floor(totalMinutes / 60); const newDate = PositionUtils.dateService.createDateAtTime(date, totalMinutes);
const minutes = totalMinutes % 60;
const newDate = new Date(date);
newDate.setHours(hours, minutes, 0, 0);
return newDate.toISOString(); return newDate.toISOString();
} }