From 2422e847b15f653465ad6f552fe1861a63280d26 Mon Sep 17 00:00:00 2001 From: sam detweiler Date: Mon, 12 May 2025 16:39:36 -0500 Subject: [PATCH] Fix calendar rrule until where event is fullday but rrule until has a non-0 time (#3782) This fixes #3781 tests supplied see https://forum.magicmirror.builders/topic/19637/issue-with-outlook-recurring-events --- CHANGELOG.md | 4 +++ .../default/calendar/calendarfetcherutils.js | 7 +++++ .../configs/modules/calendar/fullday_until.js | 27 ++++++++++++++++++ tests/electron/modules/calendar_spec.js | 4 +++ tests/mocks/fullday_until.ics | 28 +++++++++++++++++++ 5 files changed, 70 insertions(+) create mode 100644 tests/configs/modules/calendar/fullday_until.js create mode 100644 tests/mocks/fullday_until.ics diff --git a/CHANGELOG.md b/CHANGELOG.md index 752b451b..37cd41cf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,10 @@ planned for 2025-07-01 - [workflow] Run linter und spellcheck with LTS node version (#3767) - [workflow] Split "Run test" step into two steps for more clarity (#3767) +### Fixed + +- [calendar] fix fullday event rrule until with timezone offset (#3781) + ### Updated - [core] Update dependencies diff --git a/modules/default/calendar/calendarfetcherutils.js b/modules/default/calendar/calendarfetcherutils.js index df567af4..c61fd330 100644 --- a/modules/default/calendar/calendarfetcherutils.js +++ b/modules/default/calendar/calendarfetcherutils.js @@ -293,6 +293,13 @@ const CalendarFetcherUtils = { event.start = rule.options.dtstart; + // if until is set, and its a full day event, force the time to midnight. rrule gets confused with non-00 offset + // looks like MS Outlook sets the until time incorrectly for fullday events + if ((rule.options.until !== undefined) && CalendarFetcherUtils.isFullDayEvent(event)) { + Log.debug("fixup rrule until"); + rule.options.until = new Date(new Date(moment(rule.options.until).startOf("day").add(1, "day")).getTime()); + } + Log.debug("fix rrule start=", rule.options.dtstart); Log.debug("event before rrule.between=", JSON.stringify(event, null, 2), "exdates=", event.exdate); // fixup the exdate and recurrence date to local time too for post between() handling diff --git a/tests/configs/modules/calendar/fullday_until.js b/tests/configs/modules/calendar/fullday_until.js new file mode 100644 index 00000000..6713d624 --- /dev/null +++ b/tests/configs/modules/calendar/fullday_until.js @@ -0,0 +1,27 @@ +let config = { + address: "0.0.0.0", + ipWhitelist: [], + timeFormat: 12, + + modules: [ + { + module: "calendar", + position: "bottom_bar", + config: { + hideDuplicates: false, + maximumEntries: 100, + calendars: [ + { + maximumEntries: 100, + url: "http://localhost:8080/tests/mocks/fullday_until.ics" + } + ] + } + } + ] +}; + +/*************** DO NOT EDIT THE LINE BELOW ***************/ +if (typeof module !== "undefined") { + module.exports = config; +} diff --git a/tests/electron/modules/calendar_spec.js b/tests/electron/modules/calendar_spec.js index 0f8ee580..b819d2dc 100644 --- a/tests/electron/modules/calendar_spec.js +++ b/tests/electron/modules/calendar_spec.js @@ -84,6 +84,10 @@ describe("Calendar module", () => { await helpers.startApplication("tests/configs/modules/calendar/rrule_until.js", "07 Mar 2024 10:38:00 GMT-07:00", [], "America/Los_Angeles"); await expect(doTestCount()).resolves.toBe(1); }); + it("Issue #3781 recurrence rrule until with date only uses timezone offset incorrectly", async () => { + await helpers.startApplication("tests/configs/modules/calendar/fullday_until.js", "01 May 2025", [], "America/Los_Angeles"); + await expect(doTestCount()).resolves.toBe(1); + }); }); /* diff --git a/tests/mocks/fullday_until.ics b/tests/mocks/fullday_until.ics new file mode 100644 index 00000000..ffdc293d --- /dev/null +++ b/tests/mocks/fullday_until.ics @@ -0,0 +1,28 @@ +BEGIN:VCALENDAR +BEGIN:VEVENT +DESCRIPTION:\n +RRULE:FREQ=YEARLY;UNTIL=20250504T230000Z;INTERVAL=1;BYMONTHDAY=5;BYMONTH=5 +UID:040000008200E00074C5B7101A82E00800000000DAEF6ED30D9FDA01000000000000000 + 010000000D37F812F0777844A93E97B96AD2D278B +SUMMARY:Person A's Birthday +DTSTART;VALUE=DATE:20250505 +DTEND;VALUE=DATE:20250506 +CLASS:PUBLIC +PRIORITY:5 +DTSTAMP:20250428T133000Z +TRANSP:TRANSPARENT +STATUS:CONFIRMED +SEQUENCE:0 +LOCATION: +X-MICROSOFT-CDO-APPT-SEQUENCE:0 +X-MICROSOFT-CDO-BUSYSTATUS:FREE +X-MICROSOFT-CDO-INTENDEDSTATUS:BUSY +X-MICROSOFT-CDO-ALLDAYEVENT:TRUE +X-MICROSOFT-CDO-IMPORTANCE:1 +X-MICROSOFT-CDO-INSTTYPE:1 +X-MICROSOFT-DONOTFORWARDMEETING:FALSE +X-MICROSOFT-DISALLOW-COUNTER:FALSE +X-MICROSOFT-REQUESTEDATTENDANCEMODE:DEFAULT +X-MICROSOFT-ISRESPONSEREQUESTED:FALSE +END:VEVENT +END:VCALENDAR