diff --git a/Ical.Net.Tests/RecurrenceTests.cs b/Ical.Net.Tests/RecurrenceTests.cs index bda5b3f4..33098e77 100644 --- a/Ical.Net.Tests/RecurrenceTests.cs +++ b/Ical.Net.Tests/RecurrenceTests.cs @@ -4208,4 +4208,43 @@ public void GetOccurrences_WithPeriodStart_ShouldConsiderDurationCorrectly() Assert.That(occurrences, Is.EqualTo(expectedDates)); } + + [Test] + [TestCase("20250715T120000", "UTC", "20260715T120000", "UTC")] + [TestCase("20250715T120000", "UTC", "20260715T140000", "Etc/GMT-2")] + [TestCase("20250715T120000", "UTC", "20260715T100000", "Etc/GMT+2")] + [TestCase("20250715T120000", "UTC", "20260715T120000", null)] + [TestCase("20250715T120000", null, "20260715T120000", "Etc/GMT-2")] + [TestCase("20250715T120000", null, "20260715T120000", "Etc/GMT+2")] + [TestCase("20250715T120000", null, "20260715T120000", "UTC")] + [TestCase("20250715T120000", null, "20260715T120000", null)] + + [TestCase("20250715T120000", "Etc/GMT-2", "20260715", null)] + [TestCase("20250715T120000", "Etc/GMT+2", "20260715", null)] + [TestCase("20250715T120000", null, "20260715", null)] + + [TestCase("20250715", null, "20260715T235959", "UTC")] + [TestCase("20250715", null, "20260715T235959", "Etc/GMT-2")] + [TestCase("20250715", null, "20260715T235959", "Etc/GMT+2")] + [TestCase("20250715", null, "20260715T235959", null)] + + [TestCase("20250715", null, "20260715", null)] + + public void GetOccurrences_WithPeriodStart_ShouldConsiderTzCorrectly(string dtStartStr, string? dtStartTzId, string periodStartStr, string? periodStartTzId) + { + var evt = new CalendarEvent(); + evt.RecurrenceRules.Add(new RecurrencePattern(FrequencyType.Yearly, 1) { Count = 3 }); + evt.Start = new CalDateTime(dtStartStr, dtStartTzId); + + var cal = new Calendar(); + cal.Events.Add(evt); + + var firstFewOccurrences = cal.GetOccurrences().Take(3).ToList(); + + var periodStart = new CalDateTime(periodStartStr, periodStartTzId); + Assert.That(cal.GetOccurrences(periodStart).First(), Is.EqualTo(firstFewOccurrences[1])); + + var nextPeriodStart = periodStart.HasTime ? periodStart.AddSeconds(1) : periodStart.AddDays(1); + Assert.That(cal.GetOccurrences(nextPeriodStart).First(), Is.EqualTo(firstFewOccurrences[2])); + } } diff --git a/Ical.Net/Evaluation/RecurrencePatternEvaluator.cs b/Ical.Net/Evaluation/RecurrencePatternEvaluator.cs index a0e286a0..6f2011e6 100644 --- a/Ical.Net/Evaluation/RecurrencePatternEvaluator.cs +++ b/Ical.Net/Evaluation/RecurrencePatternEvaluator.cs @@ -117,7 +117,6 @@ private RecurrencePattern ProcessRecurrencePattern(CalDateTime referenceDate) private IEnumerable GetDates(CalDateTime seed, CalDateTime? periodStart, RecurrencePattern pattern, EvaluationOptions? options) { - // In the first step, we work with DateTime values, so we need to convert the CalDateTime to DateTime var originalDate = seed; var seedCopy = seed; var periodStartDt = periodStart?.ToTimeZone(seed.TzId); diff --git a/Ical.Net/Evaluation/RecurrenceUtil.cs b/Ical.Net/Evaluation/RecurrenceUtil.cs index deb6ad3c..e7e9150b 100644 --- a/Ical.Net/Evaluation/RecurrenceUtil.cs +++ b/Ical.Net/Evaluation/RecurrenceUtil.cs @@ -22,15 +22,8 @@ public static IEnumerable GetOccurrences(IRecurrable recurrable, Cal return []; } - // Ensure the start time is associated with the object being queried var start = recurrable.Start; - // Change the time zone of periodStart as needed - // so they can be used during the evaluation process. - - if (periodStart != null) - periodStart = new CalDateTime(periodStart.Date, periodStart.Time, start.TzId); - var periods = evaluator.Evaluate(start, periodStart, options); if (periodStart != null) {