-
Notifications
You must be signed in to change notification settings - Fork 194
Don't skip anchors with strict matching in Calendar.RecurrenceRule. Resolve #881 #1000
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -230,12 +230,42 @@ extension Calendar { | |
case .monthly: [.second, .minute, .hour, .day] | ||
case .yearly: [.second, .minute, .hour, .day, .month] | ||
} | ||
let componentsForEnumerating = recurrence.calendar._dateComponents(components, from: start) | ||
var componentsForEnumerating = recurrence.calendar._dateComponents(components, from: start) | ||
|
||
let rangeForBaseRecurrence: Range<Date>? = nil | ||
let expansionChangesDay = dayOfYearAction == .expand || dayOfMonthAction == .expand || weekAction == .expand || weekdayAction == .expand | ||
let expansionChangesMonth = dayOfYearAction == .expand || monthAction == .expand || weekAction == .expand | ||
|
||
if expansionChangesDay, componentsForEnumerating.day != nil { | ||
// If we expand either the day of the month or weekday, then | ||
// the day of month is likely to not match that of the start | ||
// date. Reset it to 1 in the base recurrence as to not skip | ||
// "invalid" anchors, such as February 30 | ||
componentsForEnumerating.day = 1 | ||
} | ||
if expansionChangesMonth, componentsForEnumerating.month != nil { | ||
// Likewise, if we will be changing the month, reset it to 1 | ||
// in case the start date falls on a leap month | ||
componentsForEnumerating.month = 1 | ||
componentsForEnumerating.isLeapMonth = nil | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Would we also need to handle nth-weekday and yearly combination? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, good catch! Added more exhaustive checks and cleaned up the logic a bit to be easier to read |
||
if expansionChangesDay || expansionChangesMonth, weekAction == .expand, weekdayAction != .expand { | ||
// If we are expanding weeks, all expansions in a given year | ||
// will have the same weekday. Above we have reset the month | ||
// or the day of the month, so we also changed that weekday. | ||
|
||
// To specify a yearly recurrence which starts from the same | ||
// weekday, and which doesn't start from a leap day / month, | ||
// simply use `dayOfYear` of the start date | ||
componentsForEnumerating.day = nil | ||
componentsForEnumerating.month = nil | ||
componentsForEnumerating.isLeapMonth = nil | ||
let daysInWeek = recurrence.calendar.maximumRange(of: .weekday)!.count | ||
componentsForEnumerating.dayOfYear = recurrence.calendar.component(.dayOfYear, from: start) % daysInWeek // mod 7 to get the same weekday in the beginning of the year, so it's guaranteed to always exist | ||
} | ||
|
||
baseRecurrence = Calendar.DatesByMatching(calendar: recurrence.calendar, | ||
start: start, | ||
range: rangeForBaseRecurrence, | ||
range: nil, | ||
matchingComponents: componentsForEnumerating, | ||
matchingPolicy: recurrence.matchingPolicy, | ||
repeatedTimePolicy: recurrence.repeatedTimePolicy, | ||
|
@@ -335,6 +365,9 @@ extension Calendar { | |
componentCombinations.weekdays = recurrence.weekdays | ||
componentCombinations.daysOfYear = nil | ||
componentCombinations.daysOfMonth = nil | ||
if recurrence.frequency == .yearly, monthAction != .expand { | ||
componentCombinations.months = nil | ||
} | ||
} else if recurrence.frequency == .weekly || weekAction == .expand { | ||
if let weekdayIdx = components.weekday, let weekday = Locale.Weekday(weekdayIdx) { | ||
// In a weekly recurrence (or one that expands weeks of year), we want results to fall on the same weekday as the initial date | ||
|
Uh oh!
There was an error while loading. Please reload this page.