RecurrenceRule Class
Represents a recurrence rule as defined in RFC 5545 for recurring events.
public abstract class RecurrenceRule : IRecurrenceRuleRemarks
Supports the following RFC 5545 recurrence rule properties:
- FREQ (Secondly, Minutely, Hourly, Daily, Weekly, Monthly, Yearly)
- INTERVAL - The interval between occurrences
- COUNT - Maximum number of occurrences
- UNTIL - End date for the recurrence
- WKST - The day on which the workweek starts
- BYSECOND - Limits occurrences to specific seconds (0-60; 60 denotes a leap second and is normalized to 59)
- BYMINUTE - Limits occurrences to specific minutes (0-59)
- BYHOUR - Limits occurrences to specific hours (0-23)
- BYDAY - Limits occurrences to specific days of the week
- BYMONTHDAY - Limits occurrences to specific days of the month (1-31, -1 to -31), not when FREQ is WEEKLY
- BYYEARDAY - Limits occurrences to specific days of the year (1-366, -1 to -366), not when FREQ is DAILY, WEEKLY or MONTHLY
- BYWEEKNO - Limits occurrences to specific weeks of the year (1-53, -1 to -53), only when FREQ is YEARLY
- BYMONTH - Limits occurrences to specific months (1-12)
- BYSETPOS - Limits occurrences to specific positions in the recurrence set (1-366, -1 to -366), only with another BYxxx rule part
- RSCALE and SKIP (RFC 7529) - Only their GREGORIAN and OMIT values, which are the default behavior
An RFC 2445 extension rule part, whose name starts with X-, is kept in RecurrenceRule.Text and ignored by the evaluation. Any other unknown rule part makes the rule invalid.
The start date of the enumeration is the DTSTART of the recurrence: COUNT and INTERVAL are counted from it.
Example
var rrule = RecurrenceRule.Parse("FREQ=DAILY;UNTIL=20000131T140000Z;BYMONTH=1");
var dtStart = new DateTime(2000, 01, 01, 09, 00, 00);
var occurrences = rrule.GetNextOccurrences(dtStart).Take(50).ToArray();
// Every day of January 2000, until the UNTIL date
Assert.HasCount(31, occurrences);
Assert.Equal(new DateTime(2000, 01, 01, 09, 00, 00), occurrences[0]);
Assert.Equal(new DateTime(2000, 01, 31, 09, 00, 00), occurrences[30]);- Implements
Constructors
| Name | Description |
|---|---|
| RecurrenceRule() |
RecurrenceRule()
RecurrenceRule.csprotected RecurrenceRule()No documentation is available.
Properties
| Name | Description |
|---|---|
| ByHours | Limits occurrences to specific hours (0-23). |
| ByMinutes | Limits occurrences to specific minutes (0-59). |
| ByMonthDays | Limits occurrences to specific days of the month (1-31, -1 to -31). It cannot be used when the frequency is weekly. |
| ByMonths | Limits occurrences to specific months (1-12). |
| BySeconds | Limits occurrences to specific seconds (0-59). A BYSECOND value of 60 denotes a leap second, which DateTime cannot represent, and is normalized to 59. |
| BySetPositions | Limits occurrences to specific positions in the recurrence set (1-366, -1 to -366). It can only be used with another BYxxx rule part. |
| EndDate | End date (inclusive) |
| Interval | The interval between occurrences. Must be greater than or equal to 1. |
| IsForever | Gets a value indicating whether the recurrence rule never ends. |
| Occurrences | The number of occurrences before the recurrence ends. |
| Text | Gets the RFC 5545 string representation of this recurrence rule. |
| WeekStart | The first day of the week for the recurrence rule. |
ByHours
RecurrenceRule.csLimits occurrences to specific hours (0-23).
ByMinutes
RecurrenceRule.csLimits occurrences to specific minutes (0-59).
ByMonthDays
RecurrenceRule.csLimits occurrences to specific days of the month (1-31, -1 to -31). It cannot be used when the frequency is weekly.
ByMonths
RecurrenceRule.csLimits occurrences to specific months (1-12).
BySeconds
RecurrenceRule.csLimits occurrences to specific seconds (0-59). A BYSECOND value of 60 denotes a leap second, which DateTime cannot represent, and is normalized to 59.
BySetPositions
RecurrenceRule.csLimits occurrences to specific positions in the recurrence set (1-366, -1 to -366). It can only be used with another BYxxx rule part.
EndDate
RecurrenceRule.csEnd date (inclusive)
public DateTime? EndDate { get; set; }Property value
Exceptions
InvalidOperationException- The value is not
nullandRecurrenceRule.Occurrencesis set.
Remarks
A DateTimeKind.Utc or DateTimeKind.Local value denotes an instant, and a DateTimeKind.Unspecified value a wall-clock reading. Parsing a UTC UNTIL, or one carrying an offset, produces a DateTimeKind.Utc value; a floating date-time or a date produces an DateTimeKind.Unspecified value, a date being stored as its first instant.
An instant bounds the occurrences generated from a DateTimeKind.Utc or DateTimeKind.Local start date, or from a DateTimeOffset, by instant, and a wall-clock reading bounds every occurrence by wall clock.
A parsed date designates the whole day, so it keeps every occurrence on that day, whatever its time. Setting this property stores a date-time. UNTIL has a precision of one second, so a date-time bounds the occurrences at that precision: an occurrence within the second of the value, such as one taking the fractional second of the start date, is kept.
UNTIL and COUNT cannot be used in the same recurrence rule, so RecurrenceRule.Occurrences must be null to set a value.
Interval
RecurrenceRule.csThe interval between occurrences. Must be greater than or equal to 1.
public int Interval { get; set; }IsForever
RecurrenceRule.csOccurrences
RecurrenceRule.csThe number of occurrences before the recurrence ends.
public int? Occurrences { get; set; }Property value
Exceptions
ArgumentOutOfRangeException- The value is negative.
InvalidOperationException- The value is not
nullandRecurrenceRule.EndDateis set.
Remarks
UNTIL and COUNT cannot be used in the same recurrence rule, so RecurrenceRule.EndDate must be null to set a value.
Text
WeekStart
RecurrenceRule.csThe first day of the week for the recurrence rule.
public DayOfWeek WeekStart { get; set; }Methods
| Name | Description |
|---|---|
| GetNextOccurrences(DateTime) | Gets all occurrences of the recurrence starting from the specified date. |
| GetNextOccurrences(DateTime, TimeZoneInfo) | Gets all occurrences of the recurrence, reading startDate as a wall-clock time in timeZone. |
| GetNextOccurrences(DateTimeOffset, TimeZoneInfo) | Gets all occurrences of the recurrence, starting from the instant startDate denotes. |
| GetNextOccurrencesInternal(DateTime) | When implemented in a derived class, generates the internal sequence of occurrence dates. |
| Parse(ReadOnlySpan<char>) | Parses a recurrence rule string according to RFC 5545 format. |
| Parse(string) | Parses a recurrence rule string according to RFC 5545 format. |
| ToString() | Returns a string that represents the current object. |
| TryParse(ReadOnlySpan<char>, RecurrenceRule?) | Attempts to parse a recurrence rule string. |
| TryParse(ReadOnlySpan<char>, RecurrenceRule?, string?) | Attempts to parse a recurrence rule string. |
| TryParse(string?, RecurrenceRule?) | Attempts to parse a recurrence rule string. |
| TryParse(string?, RecurrenceRule?, string?) | Attempts to parse a recurrence rule string. |
GetNextOccurrences overloads
GetNextOccurrences(DateTime)
RecurrenceRule.csGets all occurrences of the recurrence starting from the specified date.
public virtual IEnumerable<DateTime> GetNextOccurrences(DateTime startDate)Parameters
startDateDateTime- The start of the recurrence, as the DTSTART of an iCalendar event.
Returns
IEnumerable<DateTime> An enumerable sequence of occurrence dates.
Exceptions
InvalidOperationException- A rule part holds a value that RFC 5545 does not allow, such as a
RecurrenceRule.ByHoursvalue of 24. It is thrown when the enumeration starts.
Remarks
startDate is the start of the recurrence, not the instant to search from: COUNT counts the occurrences from it, and INTERVAL is aligned on it. To get the occurrences of a series on or after another date, enumerate from the start of the series and skip the earlier occurrences.
A rule cannot express a fraction of a second, so every occurrence takes the fractional second of startDate, as it takes the other time components the rule does not specify.
GetNextOccurrences(DateTime, TimeZoneInfo)
RecurrenceRule.csGets all occurrences of the recurrence, reading startDate as a wall-clock time in timeZone.
public virtual IEnumerable<DateTimeOffset> GetNextOccurrences(DateTime startDate, TimeZoneInfo timeZone)Parameters
startDateDateTime- The wall-clock time to start generating occurrences from. Its
DateTime.Kindis ignored. timeZoneTimeZoneInfo- The time zone the recurrence is expressed in, as an iCalendar DTSTART;TZID= would.
Returns
IEnumerable<DateTimeOffset> An enumerable sequence of occurrences, each carrying the UTC offset in effect at that occurrence.
Exceptions
ArgumentNullExceptiontimeZoneisnull.InvalidOperationException- A rule part holds a value that RFC 5545 does not allow, such as a
RecurrenceRule.ByHoursvalue of 24. It is thrown when the enumeration starts.
Remarks
The occurrences keep their wall-clock time across a daylight saving transition, so their UTC offset changes. A local time made invalid or ambiguous by a transition is resolved as RFC 5545 section 3.3.5 requires: an ambiguous time keeps its first occurrence, and an invalid time is read with the UTC offset in effect before the gap.
A time inside the gap of a forward transition therefore moves forward by the length of the gap, which can place its instance after the instances of the times that follow it: the occurrences are still returned in increasing order. An instance that denotes the same instant as another one, as the hour skipped by a forward transition does for an hourly recurrence, is ignored as RFC 5545 section 3.8.5.3 requires. COUNT counts the instances in the order the recurrence generates their wall-clock times, and a duplicate does not count again. Across a backward transition, the instants of the repeated hour are skipped.
An occurrence outside the range of DateTimeOffset is not returned: the enumeration ends at the first one after the range.
GetNextOccurrences(DateTimeOffset, TimeZoneInfo)
RecurrenceRule.csGets all occurrences of the recurrence, starting from the instant startDate denotes.
public IEnumerable<DateTimeOffset> GetNextOccurrences(DateTimeOffset startDate, TimeZoneInfo timeZone)Parameters
startDateDateTimeOffset- The instant to start generating occurrences from. It is reduced to a wall-clock time in
timeZone. timeZoneTimeZoneInfo- The time zone the recurrence is expressed in, as an iCalendar DTSTART;TZID= would.
Returns
IEnumerable<DateTimeOffset> An enumerable sequence of occurrences, each carrying the UTC offset in effect at that occurrence.
Exceptions
ArgumentNullExceptiontimeZoneisnull.
Remarks
The recurrence starts at the wall-clock reading of startDate, as it would with a DTSTART;TZID= holding that reading, but no occurrence before startDate is returned.
Reducing an instant to a wall-clock time is lossy in the hour repeated by a backward transition, where both readings denote the same wall clock and RFC 5545 section 3.3.5 means the first one. When startDate is the second one, the instances of the repeated hour denote instants before it and are not returned, although they still count towards COUNT. Use the DateTime overload to start from the first reading.
GetNextOccurrencesInternal(DateTime)
When implemented in a derived class, generates the internal sequence of occurrence dates.
protected abstract IEnumerable<DateTime> GetNextOccurrencesInternal(DateTime startDate)Parameters
startDateDateTime- The date to start generating occurrences from.
Returns
IEnumerable<DateTime> An enumerable sequence of occurrence dates.
Parse overloads
Parse(ReadOnlySpan<char>)
RecurrenceRule.csParses a recurrence rule string according to RFC 5545 format.
public static RecurrenceRule Parse(ReadOnlySpan<char> rrule)Parameters
rruleReadOnlySpan<char>- The recurrence rule string to parse.
Returns
RecurrenceRule A RecurrenceRule instance representing the parsed rule.
Exceptions
FormatException- Thrown when the recurrence rule format is invalid.
Parse(string)
RecurrenceRule.csParses a recurrence rule string according to RFC 5545 format.
public static RecurrenceRule Parse(string rrule)Parameters
rrulestring- The recurrence rule string to parse.
Returns
RecurrenceRule A RecurrenceRule instance representing the parsed rule.
Exceptions
FormatException- Thrown when the recurrence rule format is invalid.
ArgumentNullExceptionrruleisnull.
ToString()
RecurrenceRule.csTryParse overloads
TryParse(ReadOnlySpan<char>, RecurrenceRule?)
RecurrenceRule.csAttempts to parse a recurrence rule string.
public static bool TryParse(ReadOnlySpan<char> rrule, out RecurrenceRule? recurrenceRule)Parameters
rruleReadOnlySpan<char>- The recurrence rule string to parse.
recurrenceRuleRecurrenceRule?- When successful, contains the parsed recurrence rule.
Returns
bool true if parsing succeeded; otherwise, false.
TryParse(ReadOnlySpan<char>, RecurrenceRule?, string?)
RecurrenceRule.csAttempts to parse a recurrence rule string.
public static bool TryParse(ReadOnlySpan<char> rrule, out RecurrenceRule? recurrenceRule, out string? error)Parameters
rruleReadOnlySpan<char>- The recurrence rule string to parse.
recurrenceRuleRecurrenceRule?- When successful, contains the parsed recurrence rule.
errorstring?- When parsing fails, contains the error message.
Returns
bool true if parsing succeeded; otherwise, false.
TryParse(string?, RecurrenceRule?)
RecurrenceRule.csAttempts to parse a recurrence rule string.
public static bool TryParse(string? rrule, out RecurrenceRule? recurrenceRule)Parameters
rrulestring?- The recurrence rule string to parse.
recurrenceRuleRecurrenceRule?- When successful, contains the parsed recurrence rule.
Returns
bool true if parsing succeeded; otherwise, false.
TryParse(string?, RecurrenceRule?, string?)
RecurrenceRule.csAttempts to parse a recurrence rule string.
public static bool TryParse(string? rrule, out RecurrenceRule? recurrenceRule, out string? error)Parameters
rrulestring?- The recurrence rule string to parse.
recurrenceRuleRecurrenceRule?- When successful, contains the parsed recurrence rule.
errorstring?- When parsing fails, contains the error message.
Returns
bool true if parsing succeeded; otherwise, false.
Fields
| Name | Description |
|---|---|
| DefaultFirstDayOfWeek | The default first day of the week (Monday). |
DefaultFirstDayOfWeek
The default first day of the week (Monday).
public static readonly DayOfWeek DefaultFirstDayOfWeekConstants
| Name | Description |
|---|---|
| DefaultFirstDayOfWeekString | The string representation of the default first day of the week. |
DefaultFirstDayOfWeekString
The string representation of the default first day of the week.
public const string DefaultFirstDayOfWeekString = "MO"