Google calendar incorrect imports DDay multiple-day events - c#

I'm using a DDay library to create iCal file. Here's an example of one event that I created:
BEGIN:VCALENDAR
VERSION:2.0
METHOD:PUBLISH
PRODID:-//MyProduct
BEGIN:VEVENT
CATEGORIES:Office event
DESCRIPTION:Rudniy\, Kazahstan office has a work day.
DTEND;VALUE=DATE:20141207
DTSTAMP:20141230T085900Z
DTSTART;VALUE=DATE:20141206
SEQUENCE:0
SUMMARY:Work Day in RDN
UID:6418abbe-1904-40c4-8544-e87dd4f4c002
END:VEVENT
END:VCALENDAR
When I import that calendar to Google Calendar, the result event is only on 2014-12-06 and is one day long (instead of two).
Can please somebody tell what's wrong?

When you use end.date and start date properties, you will give date in the format "yyyy-mm-dd". In google calendar, these properties are used to create ONLY "All-day events". Here is link for the details on using properties.
Try using the properties end.dateTime(format is 2015-01-03T10:00:00.000-07:00) and start.dateTime properties to create multiple-day events.

Okay, finally I got it. The END date specifies NON-INCLUSIVE end date for event. So I just should add 1 day to each end date by myself.

Related

How to extract data using Ical.Net?

I have an ics file I want to read data out from. I downloaded Ical.Net using Nuget and I'm trying to figure out how to work with it. All I want to do is get the same info as I would get if I uploaded my ics file to this website: https://icsconvert.appspot.com/
Which is, for each "event":
Summary
Description
Start
End
Location
But I don't understand how I can get that info out of the file. Here's what I have so far:
string filepath = #"C:\My\file\path\myIcs.ics";
System.IO.StreamReader file = new System.IO.StreamReader(filepath);
string content = file.ReadToEnd();
file.Close();
Ical.Net.Calendar calendar = Ical.Net.Calendar.Load(content);
foreach (var c in calendar.RecurringItems)
{
// 1. Do something!
// 2. ????
// 3. Profit!
}
Here's a sample file I got from here:
BEGIN:VCALENDAR
VERSION:2.0
CALSCALE:GREGORIAN
BEGIN:VEVENT
SUMMARY:Access-A-Ride Pickup
DTSTART;TZID=America/New_York:20130802T103400
DTEND;TZID=America/New_York:20130802T110400
LOCATION:1000 Broadway Ave.\, Brooklyn
DESCRIPTION: Access-A-Ride trip to 900 Jay St.\, Brooklyn
STATUS:CONFIRMED
SEQUENCE:3
BEGIN:VALARM
TRIGGER:-PT10M
DESCRIPTION:Pickup Reminder
ACTION:DISPLAY
END:VALARM
END:VEVENT
BEGIN:VEVENT
SUMMARY:Access-A-Ride Pickup
DTSTART;TZID=America/New_York:20130802T200000
DTEND;TZID=America/New_York:20130802T203000
LOCATION:900 Jay St.\, Brooklyn
DESCRIPTION: Access-A-Ride trip to 1000 Broadway Ave.\, Brooklyn
STATUS:CONFIRMED
SEQUENCE:3
BEGIN:VALARM
TRIGGER:-PT10M
DESCRIPTION:Pickup Reminder
ACTION:DISPLAY
END:VALARM
END:VEVENT
END:VCALENDAR
How can I get the data I want? I want to use the foreach to save that data into a custom list.
As far as I can see you just have a set of two separate events there, not recurring events (as in defined with an RRULE).
I think you would likely find what you need in calendar.Events instead (I've never used this library, just had a quick poke at the source code and it looks like the calendar class has an "Events" property).

Recurring events lose automatic timezone conversion

I'm setting up a calendar invite email using ical.net. Sending out a non-recurring event seems to work perfectly: I set the start and end date like this
iCalEvent.DtStart = new CalDateTime(DateTime.SpecifyKind(model.EventTime.Value, DateTimeKind.Utc));
iCalEvent.DtEnd = new CalDateTime(DateTime.SpecifyKind(model.EventTime.Value.AddMinutes(model.DurationMins.Value), DateTimeKind.Utc));
when the email arrives, the time zone has been converted to the recipients timezone (The timezone is -7, the eventTime is 4pm and the duration is 3 hours)
However, when I take this same exact code and add this line to it
IRecurrencePattern recurrence = new RecurrencePattern(FrequencyType.Daily, 1)
{
Until = DateTime.SpecifyKind(model.endDate.Value.AddDays(1), DateTimeKind.Utc)
};
iCalEvent.RecurrenceRules = new List<IRecurrencePattern> { recurrence };
Suddenly my timezone is no longer converted when the email is received (The timezone is -7, the eventTime is 4pm and the duration is 3 hours. The endDate is on the 28th)
I need the DateTime to be displayed to the user in their own timezone and I need to display recurring events from the eventTime to the endDate
It may also be useful to note that I do not have a timezone property specified on Calendar as it was causing the sent email to show a "not supported calendar message" in outlook. Before I removed it, it looked like this
iCal.AddTimeZone(new VTimeZone("UTC"));
when I opened ical files that had this time zone specified, they seemed to work correctly for multi day events, but as I need them to appear in outlook with the accept/decline/tentative buttons, it is out of the question to add it back
i've also tried specifying datetimes like this
iCalEvent.DtStart = new CalDateTime(leEvent.EventTime.Value, "UTC");
but nothing changed
EDIT: I now understand that the issue is due to a recurring event needing a timezone as specified here, but I'm not quite sure where the timezone needs to be specified. I went back to adding the vTimeZone back in and validating it through this site, and it appears that the iCal file is missing the standard/daylight section inside of the timezone block
I have also tried specifying the timezone as GMT and specifying the timezone as "\"America/Phoenix\"" so that the tzid came out as TZID:"America/Phoenix" (with quotes in the ical file.
This is my code at the moment that causes the issue.
iCalEvent.DtStart = new CalDateTime(DateTime.SpecifyKind(model.EventTime.Value, DateTimeKind.Utc));
iCalEvent.DtEnd = new CalDateTime(iCalEvent.DtStart.Value.AddMinutes(model.DurationMins.Value));
if (model.EndDate.HasValue)
{
IRecurrencePattern recurrence = new RecurrencePattern(FrequencyType.Daily, 1)
{
Until = DateTime.SpecifyKind(model.MaxDate.Value, DateTimeKind.Utc).ToLocalTime()
};
iCalEvent.RecurrenceRules = new List<IRecurrencePattern> { recurrence };
iCalEvent.DtStart = new CalDateTime(iCalEvent.DtStart.Value.ToLocalTime(), "America/Phoenix");
iCalEvent.DtEnd = new CalDateTime(iCalEvent.DtEnd.Value.ToLocalTime(), "America/Phoenix");
iCal.AddTimeZone(new VTimeZone("America/Phoenix"));
}
I'm not quite sure what needs to happen to correct the standard/daylight ical error from this point.
FINAL EDIT:
after reading through this post, I found that this issue has already been solved as of last november. I checked the version we had in our project and it turned out some genius just copied the dll straight in without setting it up through nuget (and a version from several years ago no less). I grabbed the latest version and this time specifying the timezone caused no issues in outlook. I'm still experimenting with addTimeZone and addLocalTimeZone but I'm definitely on the right track. Thank you to rianjs for this extremely useful library. I don't know how I would possible work with this crazy calendar standard without it.
A recurring event is always relative to the sender's timezone (or rather to the event location), and not to the recipient's timezone, because of daylight saving changes which may happen at different time between the organiser and the various recipients.
So in most cases you want to use a meaningful timezone in the event (i.e. not UTC).
Then Outlook is simply showing that the event is indeed happening according to the given timezone. This is an indication that the event may not always be at the same time of day for the recipient.
Since this took me so long to figure out, I might as well share my solution in case anyone else runs into this problem and finds this.
I defined the DtStart/DtEnd with two datetimes that had kind utc
calendarEvent.DtStart = new CalDateTime(model.EventTime.Value);
calendarEvent.DtEnd = new CalDateTime(model.EventTime.Value.AddMinutes(model.DurationMins.Value));
which worked great for single day events, but with multidays I ended up doing this
if (model.EndDate.HasValue)
{
RecurrencePattern recurrence = new RecurrencePattern(FrequencyType.Daily, 1)
{
Until = model.EndDate.Value //has kind: Utc
};
var timezoneOffsetString = "Etc/GMT";
if (timezoneOffset > 0) //client time zone offset, calculated through js
{
timezoneOffsetString += "-" + timezoneOffset;
}
else if (timezoneOffset < 0)
{
timezoneOffsetString += "+" + (-1 * timezoneOffset);
}
calendar.AddTimeZone(timezoneOffsetString);
calendarEvent.DtStart = calendarEvent.DtStart.ToTimeZone(timezoneOffsetString);
calendarEvent.DtEnd = calendarEvent.DtEnd.ToTimeZone(timezoneOffsetString);
calendarEvent.RecurrenceRules = new List<RecurrencePattern> { recurrence };
}
It's not fullproof as some places may have weird dst problems, but nodatime was treating the "America/Phoenix" tzid as an LMT time, which was giving me a time that was like 28 minutes off... Besides, treating all dates as GMT is closer to the implementation we have in the rest of our app so it worked for my situation
This solution gave me the idea to piece together the Etc/GMT stuff.

how to change scheduler header text?

iam using devexpress scheduler. in my form iam using
schedulerControl1.ActiveViewType = DevExpress.XtraScheduler.SchedulerViewType.WorkWeek;
schedulerControl1.WorkWeekView.WorkTime.Start = System.TimeSpan.FromHours(7);
schedulerControl1.WorkWeekView.WorkTime.End = System.TimeSpan.FromHours(22);
schedulerControl1.WorkWeekView.ShowWorkTimeOnly = true;
schedulerControl1.WorkWeekView.ShowAllDayArea = false;
as you can see iam using workweek view, the start week setting properties was monday, but the header is displaying 10 october, 11 octoberand so on. the thing is how do i change the scheduler header to day name like monday, tuesday and so on.
n.b : if its duplicate please refer it
you can use formatting services (see Formatting Services - an example of use) for this purpose.
See Also:
Work Week View without specific dates
Refer these for the alternative way to implement this:
How to: Display Custom Day Headers
SchedulerControl.CustomDrawDayOfWeekHeader Event
How to: Custom Paint Day Headers
CustomDrawDayHeader, how to use custom captions with default background ?
Hope this help.

Migrating from DDay.Ical.Net to Ical.Net

Hi I am migrating from DDay.ical to Ical.Net nuget pacakages but I get stuck in the following code which add Timezone in DDay.Ical calendar please help
Previous code:
List<DOAppointment> lst = objResponse.Appointments;
string timeZoneName = objResponse.UserTimezone;
iCalendar calendar = new DDay.iCal.iCalendar();
var timeZone = TimeZoneInfo.FindSystemTimeZoneById(timeZoneName);
calendar.AddTimeZone(iCalTimeZone.FromSystemTimeZone(timeZone));
Migrating into Ical.Net:
List<DOAppointment> lst = objResponse.Appointments;
string timeZoneName = objResponse.UserTimezone;
Ical.Net.Calendar calendar = new Ical.Net.Calendar();
var timeZone = TimeZoneInfo.FindSystemTimeZoneById(timeZoneName);
ITimeZone tzID = timeZone;
calendar.AddTimeZone(tzID);
Here I know that calendar.AddTimezone will take ITimezone but how to pass it I am not getting please help.
VTimeZone is the concrete implementation of the ITimeZone interface. The ical.net example would look like this:
var calendar = new Ical.Net.Calendar();
// ical.net supports BCL time zones as well as IANA time zones
calendar.AddTimeZone(new VTimeZone(objResponse.UserTimezone));
In the future, I may change the VTimeZone constructor to throw an exception if the time zone string doesn't match anything known. Right now, though, it's pretty dumb. Behind the scenes, ical.net will default to the system time zone that the code is running on, if all else fails. That's probably not good.
I also added a wiki page with an adaptation of your question:
https://github.com/rianjs/ical.net/wiki/Working-with-time-zones

Outlook 2010 shows time one hour ahead

I have created following ".ics" file. When I open it in Google and iCal it shows correct time but when I open in Outlook 2010 it shows time one hour ahead. Any help?
BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//www.marudot.com//iCal Event Maker
X-WR-TIMEZONE:America/Los_Angeles
BEGIN:VEVENT
DTSTART;TZID=America/Los_Angeles:20140510T110000
DTEND;TZID=America/Los_Angeles:20140510T111500
SUMMARY:Appointment-11:00 AM-PST
DESCRIPTION:Appointment-11:00 AM-PST
LOCATION:Location: TBD
END:VEVENT
END:VCALENDAR
When using local time with timezone, adding a TZID to all date related properties is not enough. That is because there is no global registry of TZID that is understood by all clients. Hence, one must include in the iCalendar stream the timezone definition that corresponds to this TIZD.
In other words, your stream is not iCalendar compliant. Before the event (before BEGIN:VEVENT), you should have a proper VTIMEZONE definition corresponding to the TZID America/Los_Angeles. See https://www.rfc-editor.org/rfc/rfc5545#section-3.8.3.1
In your case, it would be something like:
BEGIN:VTIMEZONE
TZID:America/Los_Angeles
TZURL:http://tzurl.org/zoneinfo/America/Los_Angeles
X-LIC-LOCATION:America/Los_Angeles
BEGIN:DAYLIGHT
TZOFFSETFROM:-0800
TZOFFSETTO:-0700
TZNAME:PDT
DTSTART:20070311T020000
RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=2SU
END:DAYLIGHT
BEGIN:STANDARD
TZOFFSETFROM:-0700
TZOFFSETTO:-0800
TZNAME:PST
DTSTART:20071104T020000
RRULE:FREQ=YEARLY;BYMONTH=11;BYDAY=1SU
END:STANDARD
END:VTIMEZONE
I don't think "TZID=America/Los_Angeles" is a time zone that Outlook understand. Try to create a an appointment in Outlook and save it as an ICS file. What TZ does Outlook use?

Categories

Resources