在Swift中迭代日期范围的最有效方法是什么?

时间:2017-10-20 21:10:45

标签: ios swift

我正在构建一个Swift习惯构建应用程序。在某一时刻,用户选择他们想要创建的习惯的持续时间(以天为单位)。用户还可以选择他们想要练习的星期几(星期日,星期一,星期二等)。开始日期是他们养成习惯的那一天。

我目前有开始日期和结束日期(基于用户选择的天数)。但是,在该日期范围内,我需要提取用户选择的特定日期的日期。

我的想法是每个工作日的价值' x'在时间间隔(startDate,endDate)内,返回日历日期。但是,我尝试创建一个DateInterval,我无法迭代它,因为它不符合协议'序列'。

是否有一种有效的方法来迭代这个日期范围并提取其他日期?我还没有想到更好的方法吗?

以下是我当前的日期入门代码:

var date = Date()
var duration = 10
let calendar = Calendar.current

let dateEnding = Calendar.current.date(byAdding: .day, value: duration, to: date as Date)!

//Returns a number representing day of the week.  i.e. 1 = Sunday
let weekDay = calendar.component(.weekday, from: date)


//Initializing a time interval, based on user selected duration and start date
let timeInterval = DateInterval.init(start: date, end: dateEnding)

感谢您的帮助......

3 个答案:

答案 0 :(得分:13)

我们可以采用Strideable协议的力量:

extension Date: Strideable {
    public func distance(to other: Date) -> TimeInterval {
        return other.timeIntervalSinceReferenceDate - self.timeIntervalSinceReferenceDate
    }

    public func advanced(by n: TimeInterval) -> Date {
        return self + n
    }
}

,然后在您的函数中:

// Iterate by 1 day
// Feel free to change this variable to iterate by week, month etc.
let dayDurationInSeconds = 60*60*24
for date in stride(from: startDate, to: endDate, by: dayDurationInSeconds) {
    print(date)
}

输出:

2018-07-19 12:18:07 +0000
2018-07-20 12:18:07 +0000
2018-07-21 12:18:07 +0000
2018-07-22 12:18:07 +0000
2018-07-23 12:18:07 +0000
....

代码取自this proposal

答案 1 :(得分:6)

如果我正确理解您的问题,用户将在某些工作日核对并提供一段天数。

假设您在阵列中选择了工作日和持续时间,您可以按如下方式获取匹配日期列表:

// User selected weekdays (1 = Sunday, 7 = Saturday)
var selectedWeekdays = [2, 4, 6] // Example - Mon, Wed, Fri
var duration = 10 // Example - 10 days

let calendar = Calendar.current
var today = Date()
let dateEnding = calendar.date(byAdding: .day, value: duration, to: today)!

var matchingDates = [Date]()
// Finding matching dates at midnight - adjust as needed
let components = DateComponents(hour: 0, minute: 0, second: 0) // midnight
calendar.enumerateDates(startingAfter: today, matching: components, matchingPolicy: .nextTime) { (date, strict, stop) in
    if let date = date {
        if date <= dateEnding {
            let weekDay = calendar.component(.weekday, from: date)
            print(date, weekDay)
            if selectedWeekdays.contains(weekDay) {
                matchingDates.append(date)
            }
        } else {
            stop = true
        }
    }
}

print("Matching dates = \(matchingDates)")

答案 2 :(得分:2)

试试这个

let calendar = NSCalendar.currentCalendar()
let startDate = ...
let endDate = ...
let dateRange = calendar.dateRange(startDate: startDate,
                                     endDate: endDate,
                                   stepUnits: .Day,
                                   stepValue: 1)

for date in dateRange {
    print("It's \(date)!")
}