ical.net icon indicating copy to clipboard operation
ical.net copied to clipboard

Problems with RRULE when TZID:Europe/Stockholm

Open gonace opened this issue 3 years ago • 4 comments

Hi I've been scratching my head for a while and can't find any code issues on our side (with that said, I could have missed something). But when we're exporting calendars for the Timezone Europe/Stockholm the CET rule is incorrect.

BEGIN:VCALENDAR
CALSCALE:GREGORIAN
METHOD:PUBLISH
PRODID:-//github.com/rianjs/ical.net//NONSGML ical.net 4.0//EN
VERSION:2.0
X-WR-TIMEZONE:Europe/Stockholm
BEGIN:VTIMEZONE
TZID:Europe/Stockholm
X-LIC-LOCATION:Europe/Stockholm
BEGIN:STANDARD
DTSTART:20191027T030000
RRULE:FREQ=YEARLY;BYDAY=4SU;BYMONTH=10
TZNAME:CET
TZOFFSETFROM:+0200
TZOFFSETTO:+0100
END:STANDARD
BEGIN:DAYLIGHT
DTSTART:20200329T020000
RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=3
TZNAME:CEST
TZOFFSETFROM:+0100
TZOFFSETTO:+0200
END:DAYLIGHT
END:VTIMEZONE

Sweden changes from CEST to CET on the 30th of October which is the 5th Sunday, not the 4th.

Is this an issue with iCal.NET or something else?

Kind Regards

gonace avatar Oct 25 '21 14:10 gonace

We experience the same here. It's the same for most/all western standard time zones I think. It happens because of this bug which has been reported before and is not yet fixed...(https://github.com/rianjs/ical.net/issues/444): `

    private class IntervalRecurrencePattern : RecurrencePattern
    {
        public IntervalRecurrencePattern(ZoneInterval interval)
        {
            Frequency = FrequencyType.Yearly;
            ByMonth.Add(interval.IsoLocalStart.Month);

            var date = interval.IsoLocalStart.ToDateTimeUnspecified();
            var weekday = date.DayOfWeek;
            var num = DateUtil.WeekOfMonth(date);

            ByDay.Add(num != 5 ? new WeekDay(weekday, num) : new WeekDay(weekday, -1));
        }
    }


    public static int WeekOfMonth(DateTime d)
    {
        var isExact = d.Day % 7 == 0;
        var offset = isExact
            ? 0
            : 1;
        return (int) Math.Floor(d.Day / 7.0) + offset;
    }

`

The datetime used here is "DTSTART:20191027T030000". Nodatime (probably correctly) reports it as the datetime of change according to the most recent adjustment rule.

That was the 4'th sunday that year (also the last). But this year there are 5 sundays in october. And the correct rule would be the last, not the 4th sunday. But since the old 2019 date for last sunday is used, and that was in week 4 of the month, the WeekOfMonth() returns 4 and not 5 witch would be correct for this year...and thus the rule becomes 4th sunday, not last sunday...

It is an error to assume that the datetime of the most recent adjustment rule for dst/std will be in the same week of the month for all years. It is not. And then the calculation will be off by an hour in this case. Which is very bad.

This has really caused us some grief now... The bug will only manifest itself for dates between the 4th and 5th sunday of october.

eriknuds avatar Oct 27 '21 08:10 eriknuds

I'm having the same problem setting "Europe/Rome" and "CET" as TimezoneId. The rule should definitely be the last Sunday of March/October. Is there any chance this will be fixed soon?

chiarapivetta avatar Feb 24 '22 15:02 chiarapivetta

@rianjs is this something that could be solved? When looking at the current state of pull requests they seem not to be merged (the last merged pull request is Apr 10, 2021) so for us to fix this bug, then have to wait a few months or years is sadly not an option.

gonace avatar Oct 23 '22 07:10 gonace

@chiarapivetta @eriknuds we (as in the company I work for) decided to move on and fork this repository and merged a few bug fixes that have been lying around in this repository for years.

We dislike this but concluded that we had no other choice, you can find this when searching for laget.Ical.Net.

gonace avatar Jan 20 '24 09:01 gonace