feat: replace Date constructor with parseISO for improved date handling across calendar components #25

This commit is contained in:
Linus Rath
2026-03-26 17:42:44 +01:00
parent 9b25b6d03e
commit 733e99f094
9 changed files with 22 additions and 18 deletions
+3 -2
View File
@@ -1,3 +1,4 @@
import { parseISO } from 'date-fns';
import type {
CalendarEvent,
CalendarEventAlert,
@@ -53,7 +54,7 @@ export function computeFireTime(
baseTime = new Date(event.utcEnd).getTime();
} else {
// Compute end from start + duration
const startMs = new Date(event.start).getTime();
const startMs = parseISO(event.start).getTime();
if (Number.isNaN(startMs)) return null;
const durationMin = parseDuration(event.duration);
baseTime = startMs + durationMin * 60000;
@@ -61,7 +62,7 @@ export function computeFireTime(
} else {
baseTime = event.utcStart
? new Date(event.utcStart).getTime()
: new Date(event.start).getTime();
: parseISO(event.start).getTime();
}
if (Number.isNaN(baseTime)) return null;
+2 -1
View File
@@ -1,3 +1,4 @@
import { parseISO } from 'date-fns';
import type { Email, Attachment, CalendarEvent, CalendarParticipant, EmailBodyPart } from '@/lib/jmap/types';
export type InvitationMethod =
@@ -534,7 +535,7 @@ function addDurationToDate(start: string, duration: string, _timeZone?: string |
const minutes = parseInt(match[4] || '0');
const seconds = parseInt(match[5] || '0');
const date = new Date(start);
const date = parseISO(start);
if (isNaN(date.getTime())) return null;
const isUTC = start.endsWith('Z') || start.includes('+');
+5 -5
View File
@@ -12,14 +12,14 @@ export interface CalendarWeekSegment {
}
export function getEventEndDate(event: CalendarEvent): Date {
const start = new Date(event.start);
const start = parseISO(event.start);
if (!event.duration) return start;
return new Date(start.getTime() + parseDuration(event.duration) * 60000);
}
export function getEventDisplayEndDate(event: CalendarEvent): Date {
const end = getEventEndDate(event);
if (!event.showWithoutTime || end.getTime() <= new Date(event.start).getTime()) {
if (!event.showWithoutTime || end.getTime() <= parseISO(event.start).getTime()) {
return end;
}
return subMilliseconds(end, 1);
@@ -27,7 +27,7 @@ export function getEventDisplayEndDate(event: CalendarEvent): Date {
export function getEventDayBounds(event: CalendarEvent): { startDay: Date; endDay: Date } {
return {
startDay: startOfDay(new Date(event.start)),
startDay: startOfDay(parseISO(event.start)),
endDay: startOfDay(getEventDisplayEndDate(event)),
};
}
@@ -77,7 +77,7 @@ export function buildWeekSegments(events: CalendarEvent[], weekDays: Date[]): Ca
if (left.event.showWithoutTime !== right.event.showWithoutTime) {
return left.event.showWithoutTime ? -1 : 1;
}
const timeDiff = new Date(left.event.start).getTime() - new Date(right.event.start).getTime();
const timeDiff = parseISO(left.event.start).getTime() - parseISO(right.event.start).getTime();
if (timeDiff !== 0) return timeDiff;
return (left.event.title || "").localeCompare(right.event.title || "");
});
@@ -100,7 +100,7 @@ export function layoutOverlappingEvents(
events: CalendarEvent[],
): { event: CalendarEvent; column: number; totalColumns: number }[] {
const sorted = [...events].sort((a, b) => {
const diff = new Date(a.start).getTime() - new Date(b.start).getTime();
const diff = parseISO(a.start).getTime() - parseISO(b.start).getTime();
if (diff !== 0) return diff;
return parseDuration(b.duration) - parseDuration(a.duration);
});