Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does DDay Ical library calculate recurring rules correctly?

I've run some tests. Here is my code:

var systemTimeZone = TimeZoneInfo.FindSystemTimeZoneById("Pacific Standard Time");
var icalTimeZone = iCalTimeZone.FromSystemTimeZone(systemTimeZone);

var startTimeSearch = new DateTime(2015, 9, 8, 0, 0, 0, DateTimeKind.Utc);
var endTimeSearch = new DateTime(2015, 12, 1, 00, 0, 0, DateTimeKind.Utc);

var iCalendar = new iCalendar();
var pacificTimeZone = _iCalendar.AddTimeZone(icalTimeZone);

var event = new Event
{
    Summary = "This is an event at 2015-09-08 10:30 PST (2015-09-08 17:30 UTC)",
    DTStart = new iCalDateTime(2015, 9, 8, 10, 30, 0, pacificTimeZone.TZID, iCalendar),
    Duration = new TimeSpan(0, 1, 0, 0)
};

var rp = new RecurrencePattern("FREQ=WEEKLY;UNTIL=20151112T080000Z;WKST=SU;BYDAY=TU");

event.RecurrenceRules.Add(rp);
iCalendar.Events.Add(_event);
var occurrences = iCalendar.GetOccurrences(startTimeSearch, endTimeSearch);

Here's the result:

10 occurences - here are the occurences' Period.StartTime.Value and UTC properties

Value - 9/8/2015 10:30:00 - UTC 9/8/2015 17:30:00
Value - 9/15/2015 10:30:00 - UTC 9/15/2015 17:30:00
Value - 9/22/2015 10:30:00 - UTC 9/22/2015 17:30:00
Value - 9/29/2015 10:30:00 - UTC 9/29/2015 17:30:00
Value - 10/6/2015 10:30:00 - UTC 10/6/2015 17:30:00
Value - 10/13/2015 10:30:00 - UTC 10/13/2015 17:30:00
Value - 10/20/2015 10:30:00 - UTC 10/20/2015 17:30:00
Value - 10/27/2015 10:30:00 - UTC 10/27/2015 17:30:00
Value -11/3/2015 10:30:00 - UTC 11/3/2015 17:30:00 (THIS SHOULD BE 18:30:00!)
Value - 11/10/2015 10:30:00 - UTC 11/10/2015 17:30:00 (THIS SHOULD BE 18:30:00!)

enter image description here

As you can see, the last two should have a UTC time of 18:30:00. So I'm wondering if this is just the way DDay Ical works and I shouldn't count on it getting the UTC datetime right, or if I'm doing something wrong.

like image 305
richard Avatar asked Jun 25 '16 06:06

richard


2 Answers

You are getting this time difference due to daylight savings. One possible solution is not to get the time zone by name Pacific Standard Time

 // First load a file containing time zone information for Pacific Standard Time
var systemTimeZone = TimeZoneInfo.FindSystemTimeZoneById("Pacific Standard Time");

In place of this use system time zone like

var systemTimeZone = TimeZoneInfo.GetSystemTimeZones().FirstOrDefault();

Or simply add the local timezone:

iCalendar iCalendar= new iCalendar();
iCalendar.AddLocalTimeZone();

To find all registered timezones, click here

ReadOnlyCollection<TimeZoneInfo> zones = TimeZoneInfo.GetSystemTimeZones();
Console.WriteLine("The local system has the following {0} time zones", zones.Count);
foreach (TimeZoneInfo zone in zones)
   Console.WriteLine(zone.Id);

I simply use GetSystemTimeZones() in my code like

public static void Test1()
    {
        var systemTimeZone = TimeZoneInfo.GetSystemTimeZones().FirstOrDefault();
        //TimeZoneInfo.FindSystemTimeZoneById("Pacific Standard Time");
        var icalTimeZone = iCalTimeZone.FromSystemTimeZone(systemTimeZone);

        var startTimeSearch = new DateTime(2015, 9, 8, 0, 0, 0, DateTimeKind.Utc);
        var endTimeSearch = new DateTime(2015, 12, 1, 00, 0, 0, DateTimeKind.Utc);

        var iCalendar = new iCalendar();
        var pacificTimeZone = iCalendar.AddTimeZone(icalTimeZone);

        var _event =
        new Event
        {
            Summary = "This is an event at 2015-09-08 10:30 PST (2015-09-08 17:30 UTC)",
            DTStart = new iCalDateTime(2015, 9, 8, 10, 30, 0, pacificTimeZone.TZID, iCalendar),
            Duration = new TimeSpan(0, 1, 0, 0)
        };

        var rp = new RecurrencePattern("FREQ=WEEKLY;UNTIL=20151112T080000Z;WKST=SU;BYDAY=TU");

        _event.RecurrenceRules.Add(rp);
        iCalendar.Events.Add(_event);

        var occurrences = iCalendar.GetOccurrences(startTimeSearch, endTimeSearch);
    }

when I debug it got got output like

stack

you can change the time zone accordingly and get the result. Hope it helps you.

like image 152
MANISH KUMAR CHOUDHARY Avatar answered Oct 13 '22 14:10

MANISH KUMAR CHOUDHARY


Don't use dday.ical; use ical.net.

This should get you started:

var iCalendar = new Calendar();

var start = new DateTime(2015, 9, 8, 10, 30, 0);
var e = new Event
{
    Summary = "This is an event at 2015-09-08 10:30 PST (2015-09-08 17:30 UTC)",
    DtStart = new CalDateTime(start, "Pacific Standard Time"),
    Duration = TimeSpan.FromHours(1)
};

var rp = new RecurrencePattern("FREQ=WEEKLY;UNTIL=20151112T080000Z;WKST=SU;BYDAY=TU");
e.RecurrenceRules.Add(rp);
iCalendar.Events.Add(e);

var startTimeSearch = new DateTime(2015, 9, 8, 0, 0, 0, DateTimeKind.Utc);
var endTimeSearch = new DateTime(2015, 12, 1, 00, 0, 0, DateTimeKind.Utc);
var occurrences = iCalendar.GetOccurrences(startTimeSearch, endTimeSearch);

Results:

ical-net-recurrence-result

like image 23
rianjs Avatar answered Oct 13 '22 14:10

rianjs