Skip to content

Instantly share code, notes, and snippets.

@karwa
Last active January 23, 2018 00:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save karwa/6eb523c59597f2e6e88b66d8aa772844 to your computer and use it in GitHub Desktop.
Save karwa/6eb523c59597f2e6e88b66d8aa772844 to your computer and use it in GitHub Desktop.
import Foundation
private extension DateComponents {
func scaled(by: Int) -> DateComponents {
let s: (Int?)->Int? = { $0.map { $0 * by } }
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))
}
}
extension Calendar {
func makeIterator(components: DateComponents, from date: Date, until: Date?) -> Calendar.DateComponentsIterator {
return DateComponentsIterator(calendar: self, startDate: date, cutoff: until, components: components, count: 1)
}
func makeIterator(every component: Component, stride: Int = 1, from date: Date, until: Date?) -> Calendar.DateComponentsIterator {
var components = DateComponents(); components.setValue(stride, for: component)
return makeIterator(components: components, from: date, until: until)
}
struct DateComponentsIterator: IteratorProtocol {
let calendar: Calendar
let startDate: Date
let cutoff: Date?
let components: DateComponents
var count: Optional<Int> = 1
mutating func next() -> Date? {
guard let count = self.count else { return nil } // Ended.
guard let nextDate = calendar.date(byAdding: components.scaled(by: count), to: startDate) else {
self.count = nil; return nil
}
if let cutoff = self.cutoff, nextDate > cutoff {
self.count = nil; return nil
}
self.count = count + 1
return nextDate
}
}
}
var iter = Calendar.current.makeIterator(every: .day, from: Date(), until: Date().addingTimeInterval(10_000_000))
IteratorSequence(iter).forEach { print($0) }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment