-
Notifications
You must be signed in to change notification settings - Fork 194
Calendar Sequence API #322
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
Conversation
@swift-ci test |
de8ae4b
to
fc3f82c
Compare
guard let startAt = previousResult else { | ||
// We have finished | ||
return nil | ||
} | ||
|
||
let next = calendar.date(byAdding: components, to: startAt, wrappingComponents: wrappingComponents) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This approach is susceptible to the "1+1≠2" problem in calendar math. By always adding from the previous result, we're allowing for drift to occur.
As a simple example, if the start date is "January 31" and the stride is "1 month", then the first addition will result in "February 28". The addition after that will result in "March 28", which has drifted from the likely expected value of "March 31".
The typical way to solve this is to always add from the start date, and to scale the value being added. So you start by adding one month, then two months, then three months etc; instead of adding one month every time.
This, however, gives rise to other questions about which units can be used as a stride.
DateComponents
allows you to specify values that aren't relevant to addition, such as the .calendar
, .timezone
, .weekday
, etc. It seems to me that the sequence and iterator initializers should include checks to fatalError()
if the components include values that are illogical to use as a stride.
} | ||
|
||
/// A `Sequence` of `Date`s, calculated by iterative addition of `DateComponents`. | ||
struct DatesByAdding : Sendable, Sequence { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All of these types appear to be missing visibility annotations.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These are internal types now (the public API is just some (Sequence<Date> & Sendable)
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah of course; I glossed over the type-erased return types. Thanks :)
a30c665
to
aafc8a8
Compare
guard let next else { | ||
// We have finished | ||
previousResult = nil | ||
finished = false | ||
return nil | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't this be finished = true
, since "We have finished"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes!
ca9ff44
to
809920b
Compare
@swift-ci test |
809920b
to
41fa6cd
Compare
@swift-ci test |
41fa6cd
to
4044746
Compare
@swift-ci test |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just wanted to double check that one spot
@@ -1778,7 +1800,13 @@ internal final class _CalendarICU: _CalendarProtocol, @unchecked Sendable { | |||
} while ucal_get(ucalendar, UCAL_ERA, &status) < targetEra | |||
} | |||
|
|||
if startAtUnit == .day || startAtUnit == .weekday || startAtUnit == .weekdayOrdinal { | |||
let useDayOfMonth = if #available(FoundationPreview 0.4, *) { | |||
startAtUnit == .day || startAtUnit == .weekday || startAtUnit == .weekdayOrdinal || startAtUnit == .dayOfYear |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks counter intuitive?
@swift-ci test |
67ec5f0
to
86e1efc
Compare
@swift-ci test |
1 similar comment
@swift-ci test |
be42126
to
33467bb
Compare
@swift-ci test |
33467bb
to
7c15437
Compare
@swift-ci test |
See #321 for API proposal.