Free Support Forum - aspose.com

Problem retrieving date pattern

Using the online demo, I am trying to return the 1st Wednesday of May every 2 years between 1/1/2001 and 1/1/2004. When entering this through the demo interface, the following pattern is developed:

DTSTART:20010101T103000
RRULE:FREQ=MONTHLY;UNTIL=20040101T000000Z;INTERVAL=24;BYMONTH=5;BYDAY=1WE

This only generates one date, the start date. I understand the issue with why 1/1/2001 is returned (because its the start date), but why are no other dates generated?

I'm trying to get these dates via C# code using:

RecurrencePattern pattern = new RecurrencePattern();
pattern.StartDate = Convert.ToDateTime("01/01/2001");
RecurrenceRule rule = pattern.RRules.Add();
rule.EndType = EndType.Until;
rule.Until = Convert.ToDateTime("01/01/2004");
rule.Frequency = Frequency.Monthly;
rule.Interval = 24;
rule.ByMonth.Add(5);
rule.ByDay.Add(1, DayOfWeek.Wednesday);
DateCollection dates = pattern.GenerateOccurrences();

What am I doing wrong? Thanks.

SJL

To get this pattern to work you need to change the start date to be in may like this:

DTSTART:20040501T103000
RRULE:FREQ=MONTHLY;INTERVAL=24;BYMONTH=5;BYDAY=1WE

Now, this can be discussed because I can see how it could be confusing to customers. But I must say it is a bit confusing to us as well. If anybody can interpret the following excerpts from the iCalendar standard http://www.faqs.org/rfcs/rfc2445.html (section 4.3.10 Recurrence Rule) differently, please let me know.

Here are two statements:

...Information, not contained in the rule, necessary to determine the
various recurrence instance start time and dates are derived from the
Start Time (DTSTART) entry attribute...

...If multiple BYxxx rule parts are specified, then after evaluating the
specified FREQ and INTERVAL rule parts, the BYxxx rule parts are
applied to the current set of evaluated occurrences
in the following
order: BYMONTH, BYWEEKNO, BYYEARDAY, BYMONTHDAY, BYDAY, BYHOUR,
BYMINUTE, BYSECOND and BYSETPOS; then COUNT and UNTIL are evaluated.

The way we understood and implemented looks like this:

1. FREQ and INTERVAL parts are evaluated, essentially the pattern looks like this:

DTSTART:20040101T103000
RRULE:FREQ=MONTHLY;INTERVAL=24

This gives 2004-01-01, 2006-01-01, 2008-01-01 and so on.

2. Then BYMONTH rule is applied which is essentially a filter to the current set of evaulated occurrences. It selects only those occurrences that are in May. As you can see if you start date is in January, the result set becomes emtpy.

3. BYDAY is evaluated by the current set of occurrences is already empty therefore it stays empty.

By looking at the above example I admit it sounds wrong that the start date of the pattern affects the result because you requested "1st Wednesday of May every 2 years".

But if you think about it, start date probably ALWAYS affects the result of the pattern.

In your case, even if 1st Wednesday of May was correctly selected, the year of the start date will be affecting the pattern. If the start year is 2004 you will get occurrences in 2004, 2006 and so on, but if the year is 2005 then you get occurrences in 2005, 2007.

Hello, any RFC2445 experts out there?

We talked this over here once again.

It looks like the pattern should be different. We checked what pattern is produced by MS Outlook for your example and we agree the pattern should be:

RRULE:FREQ=YEARLY;INTERVAL=2;BYDAY=WE;BYMONTH=5;BYSETPOS=1

Note it uses BYSETPOS=1 and BYDAY=WE instead of BYDAY=1WE and that makes all the difference.

I will explain more tomorrow and we will fix the demo project to generate the pattern in this way. Only the demo project is affected, the component needs no changes.

Good work, Roman. That appears to be the key. It seems to work now. Thanks for your thorough analysis and response.

SJL