Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 29 additions & 7 deletions Ical.Net.Tests/RecurrenceTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2823,21 +2823,43 @@ public void UsHolidays()
/// HasTime set to true if the beginning time had HasTime set
/// to false.
/// </summary>
[Test, Category("Recurrence")]
public void Evaluate1()
[Category("Recurrence")]
[TestCase("SECONDLY", 1, true)]
[TestCase("MINUTELY", 60, true)]
[TestCase("HOURLY", 3600, true)]
[TestCase("DAILY", 24*3600, false)]
public void Evaluate1(string freq, int secsPerInterval, bool hasTime)
{
Calendar cal = new Calendar();

CalendarEvent evt = cal.Create<CalendarEvent>();
evt.Summary = "Event summary";

// Start at midnight, UTC time
evt.Start = new CalDateTime(DateTime.SpecifyKind(DateTime.Today, DateTimeKind.Utc));
evt.Start = new CalDateTime(DateTime.SpecifyKind(DateTime.Today, DateTimeKind.Utc)) { HasTime = false };

evt.RecurrenceRules.Add(new RecurrencePattern("FREQ=MINUTELY;INTERVAL=10;COUNT=5"));
var occurrences = evt.GetOccurrences(CalDateTime.Today.AddDays(1), CalDateTime.Today.AddDays(2));
// This case (DTSTART of type DATE and FREQ=MINUTELY) is undefined in RFC 5545.
// ical.net handles the case by pretending DTSTART has the time set to midnight.
evt.RecurrenceRules.Add(new RecurrencePattern($"FREQ={freq};INTERVAL=10;COUNT=5")
{
RestrictionType = RecurrenceRestrictionType.NoRestriction,
});

foreach (var o in occurrences)
Assert.That(o.Period.StartTime.HasTime, Is.True, "All recurrences of this event should have a time set.");
var occurrences = evt.GetOccurrences(CalDateTime.Today.AddDays(-1), CalDateTime.Today.AddDays(100))
.OrderBy(x => x)
.ToList();

var startDates = occurrences.Select(x => x.Period.StartTime.Value).ToList();

var expectedStartDates = Enumerable.Range(0, 5)
.Select(i => DateTime.SpecifyKind(DateTime.Today, DateTimeKind.Utc).AddSeconds(i * secsPerInterval * 10))
.ToList();

Assert.Multiple(() =>
{
Assert.That(occurrences.Select(x => x.Period.StartTime.HasTime == hasTime), Is.All.True);
Assert.That(startDates, Is.EqualTo(expectedStartDates));
});
}

[Test, Category("Recurrence")]
Expand Down
9 changes: 9 additions & 0 deletions Ical.Net/Evaluation/RecurrencePatternEvaluator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -900,6 +900,15 @@ private Period CreatePeriod(DateTime dt, IDateTime referenceDate)

public override HashSet<Period> Evaluate(IDateTime referenceDate, DateTime periodStart, DateTime periodEnd, bool includeReferenceDateInResults)
{
if ((this.Pattern.Frequency != FrequencyType.None) && (this.Pattern.Frequency < FrequencyType.Daily) && !referenceDate.HasTime)
{
// This case is not defined by RFC 5545. We handle it by evaluating the rule
// as if referenceDate had a time (i.e. set to midnight).

referenceDate = referenceDate.Copy<IDateTime>();
referenceDate.HasTime = true;
}

// Create a recurrence pattern suitable for use during evaluation.
var pattern = ProcessRecurrencePattern(referenceDate);

Expand Down
Loading