Skip to content

[Bug] Calendar shows wrong time for recurring events created before DST #3797

@plebcity

Description

@plebcity

Environment

MagicMirror² version: 2.31.0
Node version: 22.16.0
npm version: 10.9.2
Platform: Debian Linux Docker container (karsten13/magicmirror:latest)

Which start option are you using?

npm run server

Are you using PM2?

No

Module

calendar

Have you tried disabling other modules?

  • Yes
  • No

Have you searched if someone else has already reported the issue on the forum or in the issues?

  • Yes

What did you do?

I'm loading a .ics calendar with all default config except maximumNumberOfDays (2) and fetchInterval of 15 minutes.

When I create a recurring event in March, before daylight saving time then after daylight saving time it will show 1 hour too late (10 instead of 9 for example)

What did you expect to happen?

I expected the calendar module to work with recurring events combined with DST

What actually happened?

It shows 1 hour too late for every recurring event that is created in the winter period (before DST).

Additional comments

The problem lies in the interpretation of the results from RRule, as per the logging below (I have seperated them to place comments on relevant lines):

[2025-05-31 11:45:54.434] [DEBUG] start: Tue Mar 11 2025 09:00:00 GMT+0100 (Central European Standard Time) 
[2025-05-31 11:45:54.434] [DEBUG] end:: Tue Mar 11 2025 09:15:00 GMT+0100 (Central European Standard Time) 

This seems to be interpreted fine, the event first occurence was on tuesday the 11th of March 2025 at 09:00 in the morning at Europe/Brussels time. So I would expect to see an event on monday the 2nd of May 2025 at 09:00 as this only occurs on workdays.

[2025-05-31 11:45:54.434] [DEBUG] duration: 900000 
[2025-05-31 11:45:54.434] [DEBUG] title: xxxxxxxxxxxxxxxxxxx
[2025-05-31 11:45:54.435] [DEBUG] Search for recurring events between: Sat May 31 2025 11:45:53 GMT+0200 (Central European Summer Time) and Mon Jun 02 2025 23:59:59 GMT+0200 (Central European Summer Time) 

This shows that the calendar module searching for the correct range of recurring events. Below we can see how that was passed to RRule.

[2025-05-31 11:45:54.435] [DEBUG] RRule: DTSTART;TZID=Europe/Brussels:20250311T090000
RRULE:FREQ=WEEKLY;BYDAY=FR,MO,TH,TU,WE 
[2025-05-31 11:45:54.435] [DEBUG] Title: xxxxxxxxxxxxxxxx, with dates: ["2025-06-02T09:00:00.000Z","2025-06-03T09:00:00.000Z"] 

RRule got the original DTStart from the .ics file correct, as you can see there is a timezone Europe/Brussels that is not part of the ISO-8601 datetime after it. As you can see RRule returns 2 datetimes both in UTC as per this documentation on RRule: https://github.com/jkbrzt/rrule?tab=readme-ov-file#important-use-utc-dates
On this line the timezone option is removed from RRule and therefor it will return the new datetimes in UTC format and it will not do anthing with the timezone provided in DTStart: https://github.com/MagicMirrorOrg/MagicMirror/blob/master/modules/default/calendar/calendarfetcherutils.js#L302

[2025-05-31 11:45:54.435] [DEBUG] Rule has byweekday, checking for correction 
[2025-05-31 11:45:54.435] [DEBUG] initial tz=Europe/Brussels 
[2025-05-31 11:45:54.435] [DEBUG] corrected tz=Europe/Brussels 
[2025-05-31 11:45:54.435] [DEBUG] start date/time=Tue Mar 11 2025 09:00:00 GMT+0100 (Central European Standard Time) 
[2025-05-31 11:45:54.435] [DEBUG] start offset=60 
[2025-05-31 11:45:54.435] [DEBUG] start date/time w tz =Tue Mar 11 2025 09:00:00 GMT+0100 (Central European Standard Time)

This seems fine but it is really weird that the calendar module tries to do anything with the original timezone etc.

[2025-05-31 11:45:54.435] [DEBUG] event date=Mon Jun 02 2025 11:00:00 GMT+0200 (Central European Summer Time) 
[2025-05-31 11:45:54.435] [DEBUG] event offset=120 hour=11 event date=Mon Jun 02 2025 11:00:00 GMT+0200 (Central European Summer Time) 
[2025-05-31 11:45:54.435] [DEBUG] offset 
[2025-05-31 11:45:54.435] [DEBUG] adjust down 1 hour dst change 
[2025-05-31 11:45:54.435] [DEBUG] adjustHours=-1 
[2025-05-31 11:45:54.435] [DEBUG] Applying timezone adjustment hours=-1 to Mon Jun 02 2025 11:00:00 GMT+0200 (Central European Summer Time) 

This is where it is broken, it has interpreted the result of RRule as if the datetime returned has the UTC timezone, therefor it has corrected the time to 11:00 and then for some reason there is a -1 hour adjustment???

What I think should happen is remove the Z from the returned datetime from RRule and then add the local timezone, not convert it to the local timezone. Don't ever work with just the offset if you are calculating with datetimes, always use the zone.

Participation

  • I am willing to submit a pull request for this change.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions