fix: end a zero-length event at its start instead of at midnight

This commit is contained in:
Linus Rath
2026-10-29 03:38:25 +01:00
parent f83284d7e5
commit acbd085ab4
7 changed files with 92 additions and 4 deletions
+12
View File
@@ -332,6 +332,7 @@ describe('getTimedEventBoundsForDay on DST change days', () => {
timeZone: 'Europe/Berlin',
utcStart: '2026-10-25T11:51:00Z',
utcEnd: '2026-10-25T12:16:00Z',
duration: 'PT25M',
});
expect(getTimedEventBoundsForDay(fallBack, new Date(2026, 9, 25))).toMatchObject({
startMinutes: 12 * 60 + 51,
@@ -344,6 +345,7 @@ describe('getTimedEventBoundsForDay on DST change days', () => {
timeZone: 'Europe/Berlin',
utcStart: '2026-03-29T07:00:00Z',
utcEnd: '2026-03-29T08:00:00Z',
duration: 'PT1H',
});
expect(getTimedEventBoundsForDay(springForward, new Date(2026, 2, 29))).toMatchObject({
startMinutes: 9 * 60,
@@ -354,3 +356,13 @@ describe('getTimedEventBoundsForDay on DST change days', () => {
}
});
});
describe('getEventEndDate', () => {
// #837: Stalwart stores a DTEND equal to DTSTART as no duration and ends
// the event at 23:59:59 of its day.
it('ends a timed event without a duration at its start, whatever utcEnd says', () => {
const zero = ev({ start: '2026-03-02T09:00:00', utcStart: '2026-03-02T09:00:00Z', utcEnd: '2026-03-02T23:59:59Z' });
delete (zero as Partial<CalendarEvent>).duration;
expect(getEventEndDate(zero).getTime()).toBe(getEventStartDate(zero).getTime());
});
});
+5 -1
View File
@@ -113,7 +113,11 @@ export function addDaysToLocalDateTime(value: string, days: number): string {
/** End of an event as a display date - see getEventStartDate. */
export function getEventEndDate(event: CalendarEvent): Date {
if (!event.showWithoutTime && event.utcEnd) {
// A timed event without a duration lasts zero seconds (RFC 8984's default
// PT0S). Stalwart stores a DTEND equal to DTSTART as no duration and gives
// the event a utcEnd of 23:59:59 on its start day, so it filled the rest
// of the day in the grid (#837).
if (!event.showWithoutTime && event.utcEnd && event.duration) {
const utc = parseISO(event.utcEnd);
if (!isNaN(utc.getTime())) return toDisplayDate(utc);
}