Yes, this is why the documentation makes that points. However, the suggestion to use the enumerateDates
method isn't a satisfactory replacement.
The reason, as @itaiferber mentioned above, is that the enumerateDates
method is for matching a known set of components. When you're striding through a calendar like this, you don't have a known set of components you're trying to match, but you instead have a delta you're continuously applying.
In the Jan 31 example, what would our "next matching" date components be? If we're iterating by month, then it'd presumably be all the calendar components smaller than a month. For simplicity, let's say that's just the "Day" component. But the "day" component is 31
, so if we try to find the next date matching (day = 31)
, then we'll get Mar 31
and entirely skip anything in February. So the enumerateDates
method is also not what we're looking for.
Well, scaling a DateComponents
instance by a factor is a constant-time operation. A naïve implementation would be:
extension DateComponents {
func scaling(by factor: Int) -> DateComponents {
let s: (Int?) -> Int? = { $0.map { $0 * factor } }
return DateComponents(calendar: calendar,
timeZone: timeZone,
era: s(era),
year: s(year),
month: s(month),
day: s(day),
hour: s(hour),
minute: s(minute),
second: s(second),
nanosecond: s(nanosecond),
weekday: s(weekday),
weekdayOrdinal: s(weekdayOrdinal),
quarter: s(quarter),
weekOfMonth: s(weekOfMonth),
weekOfYear: s(weekOfYear),
yearForWeekOfYear: s(yearForWeekOfYear))
}
}
And then, all things being equal, presumably the manipulation routines in ICU would spend about the same amount of time adding "13 months" as they would adding "1 month", so I don't see that being more costly either.
Anyway, the point of all of this is to say that it's absolutely interesting to consider what it would take to make Date
be Strideable. However, like I said above, this is a rare enough situation that I don't think it needs to be in the Standard Library. You could maybe make an argument for this being in Foundation, but I think it'd be best served in a dedicated DateTime library that can hold your hand and help you avoid all the weird things that go on with human perceptions of time.