In the general case in date and time programming, it's not really possible to express rules about future times using UTC as your starting point if your target time zone isn't also UTC. Time zones are socio-political, and the rules change.
To that end, the solution is to express your CalDateTime
s with local time zones. Once you've done that, GetOccurrences()
will compute the recurrence set correctly.
var start = DateTime.Parse("2017-02-01 11:00");
var end = start.AddHours(1);
var dailyUntilSummer = new RecurrencePattern(FrequencyType.Daily, 1)
{
Until = DateTime.Parse("2017-07-01 12:00"),
};
var calendarEvent = new Event
{
Start = new CalDateTime(start, "America/New_York"),
End = new CalDateTime(end, "America/New_York"),
RecurrenceRules = new List<IRecurrencePattern> { dailyUntilSummer },
};
var calendar = new Calendar();
calendar.Events.Add(calendarEvent);
var occurrences = calendar.GetOccurrences(start, start.AddMonths(6))
.Select(o => new {Local = o.Period.StartTime, Utc = o.Period.StartTime.AsUtc})
.OrderBy(o => o.Local)
.ToList();
If you set a breakpoint after occurrences
, and look at its contents, you'll see that on March 12, the UTC time goes from 16:00 to 15:00 while the local time remains stable. On March 12, America/New_York went from UTC-5 to UTC-4 when the clocks changed:
(Behind the scenes, ical.net uses NodaTime to do the time zone conversions.)