RecurrenceRule Class
Definition
- Namespace
- Bodu.Globalization.Recurrence
- Assembly
- Bodu.Globalization.Recurrence.dll
- Package
- Bodu.Globalization.Recurrence 1.0.0
Represents an immutable RFC 5545 recurrence rule (RRULE): a base Frequency refined by an
interval, an optional bound (Count or Until), and the BY rule parts, from which
the set of recurring instants relative to a start date is derived.
public sealed class RecurrenceRule : IEquatable<RecurrenceRule>, IFormattable, ISpanParsable<RecurrenceRule>, IParsable<RecurrenceRule>
- Inheritance
-
RecurrenceRule
- Implements
- Inherited Members
- Extension Methods
Remarks
A rule is constructed by parsing its textual form with Parse(string) or fluently with
RecurrenceRuleBuilder, and is expanded into concrete occurrences by the GetOccurrences and
GetNextOccurrence methods, which take the series start date as their anchor. The rule itself carries no start
date; the same rule can be applied to different starts.
Occurrence enumeration currently supports the Daily, Weekly, Monthly, and Yearly frequencies. A rule with a sub-daily frequency still parses and round-trips, but enumerating it throws NotSupportedException until that follow-on lands.
Every occurrence answer is a pure function of the arguments: no API reads the wall clock or consults the machine time zone. The DateTimeOffset overloads expand the rule on the wall-clock time of the series start and return occurrences carrying the start's offset; daylight-saving transitions are the caller's concern - a host that wants a local-time schedule across a transition re-derives the offset on each evaluation.
Properties
ByDay
Gets the weekday entries selected by the BYDAY rule part.
public IReadOnlyList<WeekDayNum> ByDay { get; }
Property Value
- IReadOnlyList<WeekDayNum>
The selected weekday entries in source order, or an empty list when the rule part is absent.
ByHour
Gets the hours selected by the BYHOUR rule part.
public IReadOnlyList<int> ByHour { get; }
Property Value
- IReadOnlyList<int>
The selected hours in source order, or an empty list when the rule part is absent.
ByMinute
Gets the minutes selected by the BYMINUTE rule part.
public IReadOnlyList<int> ByMinute { get; }
Property Value
- IReadOnlyList<int>
The selected minutes in source order, or an empty list when the rule part is absent.
ByMonth
Gets the months selected by the BYMONTH rule part.
public IReadOnlyList<int> ByMonth { get; }
Property Value
- IReadOnlyList<int>
The selected months in source order, or an empty list when the rule part is absent.
ByMonthDay
Gets the month days selected by the BYMONTHDAY rule part.
public IReadOnlyList<int> ByMonthDay { get; }
Property Value
- IReadOnlyList<int>
The selected month days in source order, or an empty list when the rule part is absent.
BySecond
Gets the seconds selected by the BYSECOND rule part.
public IReadOnlyList<int> BySecond { get; }
Property Value
- IReadOnlyList<int>
The selected seconds in source order, or an empty list when the rule part is absent.
BySetPos
Gets the set positions selected by the BYSETPOS rule part.
public IReadOnlyList<int> BySetPos { get; }
Property Value
- IReadOnlyList<int>
The selected set positions in source order, or an empty list when the rule part is absent.
ByWeekNo
Gets the week numbers selected by the BYWEEKNO rule part.
public IReadOnlyList<int> ByWeekNo { get; }
Property Value
- IReadOnlyList<int>
The selected week numbers in source order, or an empty list when the rule part is absent.
ByYearDay
Gets the year days selected by the BYYEARDAY rule part.
public IReadOnlyList<int> ByYearDay { get; }
Property Value
- IReadOnlyList<int>
The selected year days in source order, or an empty list when the rule part is absent.
Count
Gets the maximum number of occurrences the rule produces.
public int? Count { get; }
Property Value
Frequency
Gets the base period at which the rule repeats.
public RecurrenceFrequency Frequency { get; }
Property Value
- RecurrenceFrequency
The recurrence frequency, corresponding to the
FREQrule part.
Interval
Gets the positive multiple of Frequency between successive occurrences.
public int Interval { get; }
Property Value
- int
The recurrence interval;
1when theINTERVALrule part is absent.
Until
Gets the inclusive upper bound beyond which no occurrence is produced.
public DateTime? Until { get; }
Property Value
WeekStart
Gets the day on which the week starts for weekly-interval and week-number calculations.
public DayOfWeek WeekStart { get; }
Property Value
Methods
Equals(RecurrenceRule?)
Determines whether this rule is equal to another rule by comparing every component.
public bool Equals(RecurrenceRule? other)
Parameters
otherRecurrenceRuleThe rule to compare with this instance.
Returns
Equals(object?)
Determines whether this rule is equal to another object.
public override bool Equals(object? obj)
Parameters
objobjectThe object to compare with this instance.
Returns
- bool
true when
objis a RecurrenceRule equal to this instance; otherwise false.
GetHashCode()
Returns a hash code derived from the rule's scalar components.
public override int GetHashCode()
Returns
- int
A hash code for the current rule.
Remarks
GetNextOccurrence(DateTime, DateTime, bool)
Returns the first occurrence of the rule that falls after the specified instant.
public DateTime? GetNextOccurrence(DateTime start, DateTime after, bool inclusive = false)
Parameters
startDateTimeThe series start (
DTSTART) the rule is anchored to.afterDateTimeThe instant the returned occurrence must follow.
inclusivebooltrue to allow an occurrence exactly equal to
after; otherwise the occurrence must be strictly later.
Returns
Remarks
The search is bounded by the end of the representable calendar (year 9999): a rule that can never match, such as 30 February yearly, answers null rather than scanning unboundedly.
Exceptions
- NotSupportedException
Thrown when the rule uses a sub-daily frequency.
GetNextOccurrence(DateTimeOffset, DateTimeOffset, bool)
Returns the first occurrence of the rule that falls after the specified instant, preserving the start's offset.
public DateTimeOffset? GetNextOccurrence(DateTimeOffset start, DateTimeOffset after, bool inclusive = false)
Parameters
startDateTimeOffsetThe series start (
DTSTART) the rule is anchored to.afterDateTimeOffsetThe instant the returned occurrence must follow.
inclusivebooltrue to allow an occurrence exactly equal to
after; otherwise the occurrence must be strictly later.
Returns
- DateTimeOffset?
The next occurrence, or null when the rule produces none.
Exceptions
- NotSupportedException
Thrown when the rule uses a sub-daily frequency.
GetOccurrences(DateTime)
Enumerates the occurrences of the rule anchored at the specified start instant.
public IEnumerable<DateTime> GetOccurrences(DateTime start)
Parameters
startDateTimeThe series start (
DTSTART) the rule is anchored to.
Returns
- IEnumerable<DateTime>
The occurrences in ascending chronological order, each preserving the Kind of
start. The sequence is bounded when the rule declares Count or Until, and otherwise continues to the end of the representable calendar; use Take<TSource>(IEnumerable<TSource>, int) or the windowed overload to bound it.
Remarks
Whether an instant is an occurrence depends only on the rule and start, never on any query
window, so the windowed overload and this method agree on membership. The start instant is itself emitted only
when it satisfies the rule.
Exceptions
- NotSupportedException
Thrown when the rule uses a sub-daily frequency.
GetOccurrences(DateTime, DateTime, DateTime)
Enumerates the occurrences of the rule that fall within an inclusive window.
public IEnumerable<DateTime> GetOccurrences(DateTime start, DateTime from, DateTime to)
Parameters
startDateTimeThe series start (
DTSTART) the rule is anchored to.fromDateTimeThe inclusive lower bound of the window.
toDateTimeThe inclusive upper bound of the window.
Returns
- IEnumerable<DateTime>
The occurrences within
[from, to]in ascending chronological order.
Exceptions
- NotSupportedException
Thrown when the rule uses a sub-daily frequency.
GetOccurrences(DateTimeOffset)
Enumerates the occurrences of the rule anchored at the specified start, preserving its UTC offset.
public IEnumerable<DateTimeOffset> GetOccurrences(DateTimeOffset start)
Parameters
startDateTimeOffsetThe series start (
DTSTART) the rule is anchored to.
Returns
- IEnumerable<DateTimeOffset>
The occurrences in ascending chronological order, each carrying the offset of
start.
Remarks
Expansion is performed on the wall-clock time of start and the fixed offset is reattached to
each result; daylight-saving transitions are not modeled (the rule carries no time zone).
Exceptions
- NotSupportedException
Thrown when the rule uses a sub-daily frequency.
GetOccurrences(DateTimeOffset, DateTimeOffset, DateTimeOffset)
Enumerates the occurrences of the rule that fall within an inclusive window, preserving the start's offset.
public IEnumerable<DateTimeOffset> GetOccurrences(DateTimeOffset start, DateTimeOffset from, DateTimeOffset to)
Parameters
startDateTimeOffsetThe series start (
DTSTART) the rule is anchored to.fromDateTimeOffsetThe inclusive lower bound of the window.
toDateTimeOffsetThe inclusive upper bound of the window.
Returns
- IEnumerable<DateTimeOffset>
The occurrences within
[from, to]in ascending chronological order.
Exceptions
- NotSupportedException
Thrown when the rule uses a sub-daily frequency.
GetPreviousOccurrence(DateTime, DateTime, bool)
Returns the last occurrence of the rule that falls before the specified instant.
public DateTime? GetPreviousOccurrence(DateTime start, DateTime before, bool inclusive = false)
Parameters
startDateTimeThe series start (
DTSTART) the rule is anchored to.beforeDateTimeThe instant the returned occurrence must precede.
inclusivebooltrue to allow an occurrence exactly equal to
before; otherwise the occurrence must be strictly earlier.
Returns
Remarks
Due-ness evaluation is a previous-occurrence comparison - typically
lastCompleted < GetPreviousOccurrence(now, inclusive: true) - so missed occurrences coalesce
structurally: the answer is a single instant, never a backlog.
Exceptions
- NotSupportedException
Thrown when the rule uses a sub-daily frequency.
GetPreviousOccurrence(DateTimeOffset, DateTimeOffset, bool)
Returns the last occurrence of the rule that falls before the specified instant, preserving the start's offset.
public DateTimeOffset? GetPreviousOccurrence(DateTimeOffset start, DateTimeOffset before, bool inclusive = false)
Parameters
startDateTimeOffsetThe series start (
DTSTART) the rule is anchored to.beforeDateTimeOffsetThe instant the returned occurrence must precede.
inclusivebooltrue to allow an occurrence exactly equal to
before; otherwise the occurrence must be strictly earlier.
Returns
- DateTimeOffset?
The previous occurrence, or null when none precedes
before.
Exceptions
- NotSupportedException
Thrown when the rule uses a sub-daily frequency.
Parse(string)
Parses the textual form of a recurrence rule, such as FREQ=WEEKLY;INTERVAL=2;BYDAY=MO,WE,FR.
public static RecurrenceRule Parse(string s)
Parameters
sstringThe rule text to parse. An optional leading
RRULE:prefix is accepted.
Returns
- RecurrenceRule
The parsed rule.
Exceptions
- ArgumentNullException
Thrown when
sis null.- FormatException
Thrown when
sis not a valid recurrence rule.
ToString()
Returns the canonical RFC 5545 text of the rule, such as FREQ=WEEKLY;INTERVAL=2;BYDAY=MO,WE,FR.
public override string ToString()
Returns
- string
The canonical rule text, which round-trips through Parse(string).
ToString(string?)
Returns the canonical RFC 5545 text of the rule.
public string ToString(string? format)
Parameters
Returns
- string
The canonical rule text.
Exceptions
- FormatException
Thrown when
formatis not a supported specifier.
ToString(string?, IFormatProvider?)
Returns the canonical RFC 5545 text of the rule.
public string ToString(string? format, IFormatProvider? formatProvider)
Parameters
formatstringThe format specifier. Only the general specifier (
"G"or null) is supported.formatProviderIFormatProviderUnused; recurrence-rule text is culture-invariant.
Returns
- string
The canonical rule text.
Exceptions
- FormatException
Thrown when
formatis not a supported specifier.
TryParse(string?, out RecurrenceRule)
Attempts to parse the textual form of a recurrence rule.
public static bool TryParse(string? s, out RecurrenceRule result)
Parameters
sstringThe rule text to parse.
resultRecurrenceRuleThe parsed rule, or null on failure.
Returns
TryParse(string?, out RecurrenceRule, out string?)
Attempts to parse the textual form of a recurrence rule, reporting the parse defect on failure.
public static bool TryParse(string? s, out RecurrenceRule result, out string? failureMessage)
Parameters
sstringThe rule text to parse.
resultRecurrenceRuleThe parsed rule, or null on failure.
failureMessagestringnull on success; otherwise a message naming the specific defect, suitable for surfacing to the user verbatim.
Returns
Explicit Interface Implementations
Parse(ReadOnlySpan<char>, IFormatProvider?)
Parses the textual form of a recurrence rule from a character span.
static RecurrenceRule Parse(ReadOnlySpan<char> s, IFormatProvider? provider)
Parameters
sReadOnlySpan<char>The rule text to parse. An optional leading
RRULE:prefix is accepted.providerIFormatProviderUnused; recurrence-rule text is culture-invariant.
Returns
- RecurrenceRule
The parsed rule.
Exceptions
- FormatException
Thrown when
sis not a valid recurrence rule.
Parse(string, IFormatProvider?)
Parses the textual form of a recurrence rule.
static RecurrenceRule Parse(string s, IFormatProvider? provider)
Parameters
sstringThe rule text to parse. An optional leading
RRULE:prefix is accepted.providerIFormatProviderUnused; recurrence-rule text is culture-invariant.
Returns
- RecurrenceRule
The parsed rule.
Exceptions
- ArgumentNullException
Thrown when
sis null.- FormatException
Thrown when
sis not a valid recurrence rule.
TryParse(ReadOnlySpan<char>, IFormatProvider?, out RecurrenceRule)
Attempts to parse the textual form of a recurrence rule from a character span.
static bool TryParse(ReadOnlySpan<char> s, IFormatProvider? provider, out RecurrenceRule result)
Parameters
sReadOnlySpan<char>The rule text to parse.
providerIFormatProviderUnused; recurrence-rule text is culture-invariant.
resultRecurrenceRuleThe parsed rule, or null on failure.
Returns
TryParse(string?, IFormatProvider?, out RecurrenceRule)
Attempts to parse the textual form of a recurrence rule.
static bool TryParse(string? s, IFormatProvider? provider, out RecurrenceRule result)
Parameters
sstringThe rule text to parse.
providerIFormatProviderUnused; recurrence-rule text is culture-invariant.
resultRecurrenceRuleThe parsed rule, or null on failure.
Returns
Applies to
| Product | Versions |
|---|---|
| .NET | 8, 10 |