ical.net
ical.net copied to clipboard
Serialized EXDATE sometimes breaks spec
In addition, changing the source code to this, to produce an all-day event:
var now = new DateTime(2017, 1, 1);
//Repeat daily for 10 days
var rrule = new RecurrencePattern(FrequencyType.Daily, 1) { Count = 10 };
var e = new Event
{
DtStart = new CalDateTime(now),
RecurrenceRules = new List<IRecurrencePattern> { rrule },
};
var exceptionDateList = new PeriodList();
exceptionDateList.Add(new Period(new CalDateTime(now.AddDays(1))));
e.ExceptionDates.Add(exceptionDateList);
var calendar = new Calendar();
calendar.Events.Add(e);
var serializer = new CalendarSerializer(new SerializationContext());
var serializedCalendar = serializer.SerializeToString(calendar);
Produces this output in serializedCalendar
:
BEGIN:VCALENDAR
PRODID:-//github.com/rianjs/ical.net//NONSGML ical.net 2.2//EN
VERSION:2.0
BEGIN:VEVENT
DTSTAMP:20170220T144719Z
DTSTART;VALUE=DATE:20170101
EXDATE:20170102/P1D
RRULE:FREQ=DAILY;COUNT=10
SEQUENCE:0
UID:08670eeb-76ad-46d1-bbfa-2e88f1597d58
END:VEVENT
END:VCALENDAR
In this case, EXDATE breaks the spec completely, as it's a date, but VALUE=DATE hasn't been set, and it has a weird duration suffixed to it.
In the long term, it's reasonable to consider changing ExceptionDates
to not be a list of IPeriodList
s. EXDATE can only be DATE-TIME or DATE according to the standard.
In the short term, suppressing duration output when serializing to ICS, and emitting the TZID parameter, should be enough.
We had to work around this recently, because I didn't have time to fix it in the library itself... You can specify TzId via Parameters. IIRC:
exDate.Parameters.Add("TZID", "America/New_York");
You may want to check if the parameter is already present before doing a blind add, as there is no duplicate checking.
But yes, it's a bug, and should be fixed.
In this case, EXDATE breaks the spec completely, as it's a date, but VALUE=DATE hasn't been set, and it has a weird duration suffixed to it.
That "weird duration" is part of the spec: https://tools.ietf.org/html/rfc5545#section-3.3.6
That "weird duration" is part of the spec
Oh, I know that, but I meant more in terms of why it's suffixed, as EXDATE has the value types of DATE-TIME or DATE if the VALUE attribute is set, see section 3.8.5.1.
Of course, yeah, for PERIOD types you have the duration suffix, so I guess it makes sense since periods are used for values in the API.
As for why it's periods in the first place, I'm guessing there was a mix-up since RDATE supports DATE-TIME, DATE and PERIOD.
I edited your original post a bit, because I'm going to tackle #259 which should take care of the first part of your ticket.
Could someone please help, i'm banging my head against the wall with what I think is a simple issue, since everything else is working, but I just can't get this to work.
I'm using VB and trying to specify ExceptionDates. Everything compiles and "works" but the exception dates are completely ignored when doing GetOccurance.
Could someone please post a simple example (VB or C) that shows how you would add a few exception dates to the event and make it work.
Thank you!
https://stackoverflow.com/help/how-to-ask
See the section called "Help others reproduce the problem"
@rianjs trying to debug why EXDATE
won't work for me in Thunderbird and Google Calendar and it seems to be because of it being formatted as a period list with /P1D
. I understand it's part of the spec, but perhaps it would be beneficial to use a regular DATE-TIME or DATE to comply with what most Calendar clients seem to prefer?
In particular, this is the event I'm having trouble with:
BEGIN:VEVENT
DESCRIPTION:
DTEND;TZID=America/Los_Angeles:20220427T081500
DTSTAMP:20220425T095711Z
DTSTART;TZID=America/Los_Angeles:20220427T004500
EXDATE;TZID=America/Los_Angeles:20220429/P1D,20220428/P1D
RRULE:FREQ=DAILY;COUNT=3
SEQUENCE:0
SUMMARY:test
UID:42566f87-1a0e-438a-9b8d-b5b3c9d276e5
END:VEVENT
As soon as I remove the /P1D, it starts working.
Testing more now... it seems Google Calendar will only accept my EXDATE if I specify it as UTC time, offset to account for the timezone of my event. So my EXDATE has to be formatted like EXDATE:20220429T074500Z,20220428T074500Z
:/
Edit: for anyone else experiencing this, provide a date converted to UTC to CalDateTime
, and set HasTime
on the CalDateTime
to true
. That'll cause the dates to be formatted as required above.
Testing more now... it seems Google Calendar will only accept my EXDATE if I specify it as UTC time, offset to account for the timezone of my event. So my EXDATE has to be formatted like
EXDATE:20220429T074500Z,20220428T074500Z
:/Edit: for anyone else experiencing this, provide a date converted to UTC to
CalDateTime
, and setHasTime
on theCalDateTime
totrue
. That'll cause the dates to be formatted as required above.
Hey, thanks a lot @hmnd, that was really helpfull