mirror of
https://github.com/MichMich/MagicMirror.git
synced 2025-09-15 16:29:02 +00:00
Refactored calendarfetcherutils to fix many of the timezone and DST related issues and make debugging way easier (#3806)
Refactored calendarfetcherutils to remove as many of the date conversions as possible and use moment tz when calculating recurring events, this will make debugging a lot easier and fixes problems from the past with offsets and DST not being handled properly. Also added some tests to test the behavior of the refactored methodes to make sure the correct event dates are returned. Refactored calendar.js aswell to make sure the unix UTC start and end date of events are properly converted to a local timezone and displayed correctly for the user. This PR relates to: https://github.com/MagicMirrorOrg/MagicMirror/issues/3797 --------- Co-authored-by: Koen Konst <c.h.konst@avisi.nl> Co-authored-by: Kristjan ESPERANTO <35647502+KristjanESPERANTO@users.noreply.github.com>
This commit is contained in:
@@ -1,5 +1,8 @@
|
||||
global.moment = require("moment-timezone");
|
||||
|
||||
const ical = require("node-ical");
|
||||
const { expect } = require("playwright/test");
|
||||
const moment = require("moment-timezone");
|
||||
const CalendarFetcherUtils = require("../../../../../modules/default/calendar/calendarfetcherutils");
|
||||
|
||||
describe("Calendar fetcher utils test", () => {
|
||||
@@ -49,5 +52,65 @@ describe("Calendar fetcher utils test", () => {
|
||||
expect(filteredEvents[0].title).toBe("ongoingEvent");
|
||||
expect(filteredEvents[1].title).toBe("upcomingEvent");
|
||||
});
|
||||
|
||||
it("should return the correct times when recurring events pass through daylight saving time", () => {
|
||||
const data = ical.parseICS(`BEGIN:VEVENT
|
||||
DTSTART;TZID=Europe/Amsterdam:20250311T090000
|
||||
DTEND;TZID=Europe/Amsterdam:20250311T091500
|
||||
RRULE:FREQ=WEEKLY;BYDAY=FR,MO,TH,TU,WE,SA,SU
|
||||
DTSTAMP:20250531T091103Z
|
||||
ORGANIZER;CN=test:mailto:test@test.com
|
||||
UID:67e65a1d-b889-4451-8cab-5518cecb9c66
|
||||
CREATED:20230111T114612Z
|
||||
DESCRIPTION:Test
|
||||
LAST-MODIFIED:20250528T071312Z
|
||||
SEQUENCE:1
|
||||
STATUS:CONFIRMED
|
||||
SUMMARY:Test
|
||||
TRANSP:OPAQUE
|
||||
END:VEVENT`);
|
||||
|
||||
const filteredEvents = CalendarFetcherUtils.filterEvents(data, defaultConfig);
|
||||
|
||||
const januaryFirst = filteredEvents.filter((event) => moment(event.startDate, "x").format("MM-DD") === "01-01");
|
||||
const julyFirst = filteredEvents.filter((event) => moment(event.startDate, "x").format("MM-DD") === "07-01");
|
||||
|
||||
let januaryMoment = moment(`${moment(januaryFirst[0].startDate, "x").format("YYYY")}-01-01T09:00:00`)
|
||||
.tz("Europe/Amsterdam", true) // Convert to Europe/Amsterdam timezone (see event ical) but keep 9 o'clock
|
||||
.tz(moment.tz.guess()); // Convert to guessed timezone as that is used in the filterEvents
|
||||
|
||||
let julyMoment = moment(`${moment(julyFirst[0].startDate, "x").format("YYYY")}-07-01T09:00:00`)
|
||||
.tz("Europe/Amsterdam", true) // Convert to Europe/Amsterdam timezone (see event ical) but keep 9 o'clock
|
||||
.tz(moment.tz.guess()); // Convert to guessed timezone as that is used in the filterEvents
|
||||
|
||||
expect(januaryFirst[0].startDate).toEqual(januaryMoment.format("x"));
|
||||
expect(julyFirst[0].startDate).toEqual(julyMoment.format("x"));
|
||||
});
|
||||
|
||||
it("should return the correct moments based on the timezone given", () => {
|
||||
const data = ical.parseICS(`BEGIN:VEVENT
|
||||
DTSTART;TZID=Europe/Amsterdam:20250311T090000
|
||||
DTEND;TZID=Europe/Amsterdam:20250311T091500
|
||||
RRULE:FREQ=WEEKLY;BYDAY=FR,MO,TH,TU,WE,SA,SU
|
||||
DTSTAMP:20250531T091103Z
|
||||
ORGANIZER;CN=test:mailto:test@test.com
|
||||
UID:67e65a1d-b889-4451-8cab-5518cecb9c66
|
||||
CREATED:20230111T114612Z
|
||||
DESCRIPTION:Test
|
||||
LAST-MODIFIED:20250528T071312Z
|
||||
SEQUENCE:1
|
||||
STATUS:CONFIRMED
|
||||
SUMMARY:Test
|
||||
TRANSP:OPAQUE
|
||||
END:VEVENT`);
|
||||
|
||||
const moments = CalendarFetcherUtils.getMomentsFromRecurringEvent(data["67e65a1d-b889-4451-8cab-5518cecb9c66"], moment(), moment().add(365, "days"));
|
||||
|
||||
const januaryFirst = moments.filter((m) => m.format("MM-DD") === "01-01");
|
||||
const julyFirst = moments.filter((m) => m.format("MM-DD") === "07-01");
|
||||
|
||||
expect(januaryFirst[0].toISOString(true)).toContain("09:00:00.000+01:00");
|
||||
expect(julyFirst[0].toISOString(true)).toContain("09:00:00.000+02:00");
|
||||
});
|
||||
});
|
||||
});
|
||||
|
Reference in New Issue
Block a user