Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug - Invalid recurring event occurrences after New Year #342

Closed
AdamPodsiadlo opened this issue Nov 23, 2017 · 2 comments · Fixed by #673
Closed

Bug - Invalid recurring event occurrences after New Year #342

AdamPodsiadlo opened this issue Nov 23, 2017 · 2 comments · Fixed by #673
Labels

Comments

@AdamPodsiadlo
Copy link

Creating recurring event which is repeated every two weeks for all week days and starts in the middle of the week, is supposed to return occurrences until Sunday and then skips next week.

But when week ends on 31.12.2017 then occurrences for first week of the year are created.

Steps to reproduce:

  1. Add event with following RRULE:
    FREQ=WEEKLY;INTERVAL=2;BYDAY=MO,TU,WE,TH,FR,SA,SU
  2. Set event start to 30.12.2017
  3. Set event end to 29.01.2018
  4. Get event occurrences.

Actual result:

  1. 30.12.2017, 31.12.2017, 01.01.2018, 02.01.2018, 03.01.2018, 04.01.2018, 05.01.2018, 08.01.2018,
    09.01.2018, 10.01.2018, 11.01.2018, 12.01.2018, 13.01.2018, 14.01.2018, 22.01.2018, 23.01.2018,
    24.01.2018, 25.01.2018, 26.01.2018, 27.01.2018, 28.01.2018
  2. Extra invalid dates: 01.01.2018, 02.01.2018, 03.01.2018, 04.01.2018, 05.01.2018

Expeted result:
30.12.2017, 31.12.2017, 08.01.2018, 09.01.2018, 10.01.2018, 11.01.2018, 12.01.2018, 13.01.2018, 14.01.2018, 22.01.2018, 23.01.2018, 24.01.2018, 25.01.2018, 26.01.2018, 27.01.2018, 28.01.2018

UT:

    [TestFixture]
    public class Tests
    {
        private static void CheckDates(DateTime startDate, DateTime endDate, DateTime[] expectedDates)
        {
            var rule = new RecurrencePattern(FrequencyType.Weekly, 2);

            rule.ByDay = new List<WeekDay>()
            {
                new WeekDay(DayOfWeek.Monday),
                new WeekDay(DayOfWeek.Tuesday),
                new WeekDay(DayOfWeek.Wednesday),
                new WeekDay(DayOfWeek.Thursday),
                new WeekDay(DayOfWeek.Friday),
                new WeekDay(DayOfWeek.Saturday),
                new WeekDay(DayOfWeek.Sunday),
            };

            var calendarEvent = new CalendarEvent()
            {
                DtStart = new CalDateTime(startDate),
                DtEnd = new CalDateTime(endDate),
                RecurrenceRules = new List<RecurrencePattern>()
                {
                    rule
                },
            };

            var occurences = calendarEvent.GetOccurrences(startDate, endDate);

            var occurrencesDates = occurences.Select(o => o.Period.StartTime.Date).ToArray();

            CollectionAssert.AreEquivalent(expectedDates, occurrencesDates);
        }

        [Test]
        public void NewYear_EachOtherWeek()
        {
            var startDate = new DateTime(2017,12,30);
            var endDate = new DateTime(2018,1, 29);
            var expectedDates = new[]
            {
                new DateTime(2017, 12, 30),
                new DateTime(2017, 12, 31),

                // 1-7 no events
                
                new DateTime(2018, 1, 8),
                new DateTime(2018, 1, 9),
                new DateTime(2018, 1, 10),
                new DateTime(2018, 1, 11),
                new DateTime(2018, 1, 12),
                new DateTime(2018, 1, 13),
                new DateTime(2018, 1, 14),

                // 15 - 21 no events

                new DateTime(2018, 1, 22),
                new DateTime(2018, 1, 23),
                new DateTime(2018, 1, 24),
                new DateTime(2018, 1, 25),
                new DateTime(2018, 1, 26),
                new DateTime(2018, 1, 27),
                new DateTime(2018, 1, 28),
            };

            //FAILS
            CheckDates(startDate, endDate, expectedDates);
        }

        [Test]
        public void December_EachOtherWeek()
        {
            var startDate = new DateTime(2017, 12, 1);
            var endDate = new DateTime(2017, 12, 31);
            var expectedDates = new[]
            {
                new DateTime(2017, 12, 1),
                new DateTime(2017, 12, 2),
                new DateTime(2017, 12, 3),
                // 4-10 no events
                
                new DateTime(2017, 12, 11),
                new DateTime(2017, 12, 12),
                new DateTime(2017, 12, 13),
                new DateTime(2017, 12, 14),
                new DateTime(2017, 12, 15),
                new DateTime(2017, 12, 16),
                new DateTime(2017, 12, 17),

                // 18 - 24 no events

                new DateTime(2017, 12, 25),
                new DateTime(2017, 12, 26),
                new DateTime(2017, 12, 27),
                new DateTime(2017, 12, 28),
                new DateTime(2017, 12, 29),
                new DateTime(2017, 12, 30),
               // new DateTime(2017, 12, 31), 
            };

            //PASS
            CheckDates(startDate, endDate, expectedDates);
        }

        [Test]
        public void NovemberEnd_December_EachOtherWeek()
        {
            var startDate = new DateTime(2017, 11, 30);
            var endDate = new DateTime(2017, 12, 31);
            var expectedDates = new[]
            {
                new DateTime(2017, 11, 30),
                new DateTime(2017, 12, 1),
                new DateTime(2017, 12, 2),
                new DateTime(2017, 12, 3),
                // 4-10 no events
                
                new DateTime(2017, 12, 11),
                new DateTime(2017, 12, 12),
                new DateTime(2017, 12, 13),
                new DateTime(2017, 12, 14),
                new DateTime(2017, 12, 15),
                new DateTime(2017, 12, 16),
                new DateTime(2017, 12, 17),

                // 18 - 24 no events

                new DateTime(2017, 12, 25),
                new DateTime(2017, 12, 26),
                new DateTime(2017, 12, 27),
                new DateTime(2017, 12, 28),
                new DateTime(2017, 12, 29),
                new DateTime(2017, 12, 30),               
            };

            // PASS
            CheckDates(startDate, endDate, expectedDates);
        }
    }
@rianjs
Copy link
Collaborator

rianjs commented Nov 24, 2017

Creating recurring event which is repeated every two weeks for all week days and starts in the middle of the week, is supposed to return occurrences until Sunday and then skips next week.

But when week ends on 31.12.2017 then occurrences for first week of the year are created.

Steps to reproduce:

Add event with following RRULE:
FREQ=WEEKLY;INTERVAL=2;BYDAY=MO,TU,WE,TH,FR,SA,SU
**Set event start to 30.12.2017**
**Set event end to 29.01.2018**

Did you mean to create an event that's 30 days long, and recurs every other week creating a cascade of overlaps? You might want to check your expectations with respect to behavior for the event that's 30 days long...

@rianjs
Copy link
Collaborator

rianjs commented Nov 25, 2017

OK, I see what you mean.

axunonb added a commit to axunonb/ical.net that referenced this issue Dec 18, 2024
Updated `CalendarEvent` and `EventEvaluator` to enhance event handling,
particularly around time zones and daylight saving time transitions.

Key changes include:

- Enabled nullable reference types in `CalendarEvent` and `EventEvaluator.`
- Updated `CalendarEvent` to throw `InvalidOperationException` when trying to set both `DtEnd` and `Duration`.
- Event end time and duration calculations in `EventEvaluator` reflect any DST transitions.
- Added new test class `RecurrenceTests_From_Issues` to validate changes with various edge cases and scenarios.

Resolves ical-org#660
Resolves ical-org#623
Resolves ical-org#671
Resolves ical-org#567
Resolves ical-org#342
Resolves ical-org#298
axunonb added a commit to axunonb/ical.net that referenced this issue Dec 18, 2024
Updated `CalendarEvent` and `EventEvaluator` to enhance event handling,
particularly around time zones and daylight saving time transitions.

Key changes include:

- Enabled nullable reference types in `CalendarEvent` and `EventEvaluator.`
- Updated `CalendarEvent` to throw `InvalidOperationException` when trying to set both `DtEnd` and `Duration`.
- Event end time and duration calculations in `EventEvaluator` reflect any DST transitions.
- Added new test class `RecurrenceTests_From_Issues` to validate changes with various edge cases and scenarios.

Resolves ical-org#660
Resolves ical-org#623
Resolves ical-org#671
Resolves ical-org#567
Resolves ical-org#342
Resolves ical-org#298
@axunonb axunonb added the bug label Dec 18, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants