Skip to content

Introduce proposal for Calendar.RecurrenceRule#422

Merged
itingliu merged 8 commits intoswiftlang:mainfrom
hristost:hstaykov/calendar-recurrence-rule
Mar 8, 2024
Merged

Introduce proposal for Calendar.RecurrenceRule#422
itingliu merged 8 commits intoswiftlang:mainfrom
hristost:hstaykov/calendar-recurrence-rule

Conversation

@hristost
Copy link
Copy Markdown
Contributor

@hristost hristost commented Feb 15, 2024

This pull request introduces a proposal for a new type, Calendar.RecurrenceRule, that allows to describe recurring events and calculate future occurrences.

/// a yearly frequency, repeat on the n-th week of the year.
///
/// If n is negative, repeat on the n-to-last of the given weekday.
case nth(Int, Locale.Weekday)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would suggest adding conveniences like:

extension Weekday {
    public static func first(_ weekday: Locale.Weekday) -> Self { .nth(1, weekday) }
    public static func second(_ weekday: Locale.Weekday) -> Self { .nth(2, weekday) }

    public static func last(_ weekday: Locale.Weekday) -> Self { .nth(-1, weekday) }
    public static func secondToLast(_ weekday: Locale.Weekday) -> Self { .nth(-2, weekday) }
}

These are much easier to understand that .nth(-1, .wednesday).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can keep iterating it during the review period

@itingliu itingliu added API Change Any changes to Foundation's public API surface proposal This PR is for a proposal and removed API Change Any changes to Foundation's public API surface labels Feb 16, 2024
/// - Returns: a sequence of dates conforming to the recurrence rule, in
/// the given `range`. An empty sequence if the rule doesn't match any
/// dates.
public func recurrences(of start: Date,
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can see use cases for other expand methods:

  • Expand N instances (from start) - i.e. use a count instead of a range
  • Expand N instances (after instance D) - e.g., give me the next instance (N=1) instance after D

Note sure if these are things you want to include.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think both can be achieved using the existing API without a performance cost:

var count = 0
for date in recurrenceRule.recurrences(of: .now) while count < 10 {
    count += 1
    ...
}

The range argument is more necessary because it allows to skip calculating recurrences until the start of the range.

/// dates.
public func recurrences(of start: Date,
in range: Range<Date>? = nil
) -> some (Sequence<Date> & Sendable)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was there any consideration of using an AsyncSequence here? The number of items in a range could be very large for some frequencies. Also it might be more efficient for "iteratively" generated dates where the whole recurrence calculation does not have to be started for each subsequent range.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed, some recurrence rules can yield and infinite number of results. Using Sequence allows us to calculate recurrences only when requested, so we don't preemptively calculate the full set at the start of a loop. I don't think there's a need for AsyncSequence here.

hristost added a commit to hristost/swift-foundation that referenced this pull request Mar 6, 2024
This implements most of `Calendar.RecurrenceRule` as it was pitched in swiftlang#422.

To do:
- Respect RecurrenceRule.matchingPolicy
- Respect RecurrenceRule.repeatedTimePolicy
- Expand testing
hristost added a commit to hristost/swift-foundation that referenced this pull request Mar 6, 2024
This implements most of `Calendar.RecurrenceRule` as it was pitched in swiftlang#422.

To do:
- Respect RecurrenceRule.matchingPolicy
- Respect RecurrenceRule.repeatedTimePolicy
- Expand testing
/// a yearly frequency, repeat on the n-th week of the year.
///
/// If n is negative, repeat on the n-to-last of the given weekday.
case nth(Int, Locale.Weekday)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can keep iterating it during the review period

@hristost hristost force-pushed the hstaykov/calendar-recurrence-rule branch from 7839480 to be5c6b0 Compare March 6, 2024 20:51
Co-authored-by: Tina Liu <49205802+itingliu@users.noreply.github.com>
@hristost hristost force-pushed the hstaykov/calendar-recurrence-rule branch from be5c6b0 to 353f55e Compare March 6, 2024 22:07
@itingliu itingliu merged commit 56276dc into swiftlang:main Mar 8, 2024
hristost added a commit to hristost/swift-foundation that referenced this pull request Mar 15, 2024
This commit implements the `Calendar.RecurrenceRule` type first pitched in swiftlang#422.

This type models a subset of RRULE as specified in RFC-5545, section 3.3.10. One
notable difference is that it doesn't support a frequency of "secondly", as that
was not part of the original proposal. It also implements RFC-7529 Non-Gregorian
Recurrence Rules and works with any instance of `Calendar`.

Recurrences are calculated according to our interpretation of the RFCs. As such,
the resulting dates may differ in certain edge cases when compared to other open
source implementations.
hristost added a commit to hristost/swift-foundation that referenced this pull request Mar 15, 2024
This commit implements the `Calendar.RecurrenceRule` type first pitched in swiftlang#422.

This type models a subset of RRULE as specified in RFC-5545, section 3.3.10. One
notable difference is that it doesn't support a frequency of "secondly", as that
was not part of the original proposal. It also implements RFC-7529 Non-Gregorian
Recurrence Rules and works with any instance of `Calendar`.

Recurrences are calculated according to our interpretation of the RFCs. As such,
the resulting dates may differ in certain edge cases when compared to other open
source implementations.
hristost added a commit to hristost/swift-foundation that referenced this pull request Apr 2, 2024
This commit implements the `Calendar.RecurrenceRule` type first pitched in swiftlang#422.

This type models a subset of RRULE as specified in RFC-5545, section 3.3.10. One
notable difference is that it doesn't support a frequency of "secondly", as that
was not part of the original proposal. It also implements RFC-7529 Non-Gregorian
Recurrence Rules and works with any instance of `Calendar`.

Recurrences are calculated according to our interpretation of the RFCs. As such,
the resulting dates may differ in certain edge cases when compared to other open
source implementations.
hristost added a commit to hristost/swift-foundation that referenced this pull request Apr 2, 2024
This commit implements the `Calendar.RecurrenceRule` type first pitched in swiftlang#422.

This type models a subset of RRULE as specified in RFC-5545, section 3.3.10. One
notable difference is that it doesn't support a frequency of "secondly", as that
was not part of the original proposal. It also implements RFC-7529 Non-Gregorian
Recurrence Rules and works with any instance of `Calendar`.

Recurrences are calculated according to our interpretation of the RFCs. As such,
the resulting dates may differ in certain edge cases when compared to other open
source implementations.
hristost added a commit to hristost/swift-foundation that referenced this pull request Apr 30, 2024
This commit implements  `Calendar.RecurrenceRule.recurrences(of:in:)` as pitched
in swiftlang#422.

This type models a subset of RRULE as specified in RFC-5545, section 3.3.10. One
notable difference is that it doesn't support a frequency of "secondly", as that
was not part of the original proposal. It also implements RFC-7529 Non-Gregorian
Recurrence Rules and works with any instance of `Calendar`.

Recurrences are calculated according to our interpretation of the RFCs. As such,
the resulting dates may differ in certain edge cases when compared to other open
source implementations.
hristost added a commit to hristost/swift-foundation that referenced this pull request May 1, 2024
This commit implements  `Calendar.RecurrenceRule.recurrences(of:in:)` as pitched
in swiftlang#422.

This type models a subset of RRULE as specified in RFC-5545, section 3.3.10. One
notable difference is that it doesn't support a frequency of "secondly", as that
was not part of the original proposal. It also implements RFC-7529 Non-Gregorian
Recurrence Rules and works with any instance of `Calendar`.

Recurrences are calculated according to our interpretation of the RFCs. As such,
the resulting dates may differ in certain edge cases when compared to other open
source implementations.
hristost added a commit that referenced this pull request May 1, 2024
This commit implements  `Calendar.RecurrenceRule.recurrences(of:in:)` as pitched
in #422.

This type models a subset of RRULE as specified in RFC-5545, section 3.3.10. One
notable difference is that it doesn't support a frequency of "secondly", as that
was not part of the original proposal. It also implements RFC-7529 Non-Gregorian
Recurrence Rules and works with any instance of `Calendar`.

Recurrences are calculated according to our interpretation of the RFCs. As such,
the resulting dates may differ in certain edge cases when compared to other open
source implementations.
hristost added a commit to hristost/swift-foundation that referenced this pull request Sep 17, 2024
This commit implements the `Calendar.RecurrenceRule` type first pitched in swiftlang#422.

This type models a subset of RRULE as specified in RFC-5545, section 3.3.10. One
notable difference is that it doesn't support a frequency of "secondly", as that
was not part of the original proposal. It also implements RFC-7529 Non-Gregorian
Recurrence Rules and works with any instance of `Calendar`.

Recurrences are calculated according to our interpretation of the RFCs. As such,
the resulting dates may differ in certain edge cases when compared to other open
source implementations.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

proposal This PR is for a proposal

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants