Как я могу перебирать день за днем ​​от StartDate до EndDate, используя strideable на Swift? - PullRequest
1 голос
/ 31 марта 2019

Я пытаюсь создать функцию, которая получает:

-An StartDate (DATE).

-An EndDate (DATE).

Способна выполнять итерацию день за днемпечать дня в формате гггг-мм-дд

Но я получаю следующую ошибку:

"Cannot invoke 'stride' with an argument list of type '(from: Date, to: Date, by: Int)'"

Что я пробовал?

Мои даты соответствуютпростейший протокол

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
    }
}

Так что я мог бы использовать функцию шага

stride(from: <#T##Strideable#>, to: <#T##Strideable#>, by: <#T##Comparable & SignedNumeric#>)

На моем ViewDidLoad при попытке его запустить

override func viewDidLoad() {
        super.viewDidLoad()
        let formatter = DateFormatter()
        formatter.dateFormat = "yyyy/MM/dd"
        let startDate = formatter.date(from: "2014/01/01")
        let endDate = formatter.date(from: "2019/03/31")
        let dayDurationInSeconds = 60*60*24

        for date in stride(from: startDate!, to: endDate!, by: dayDurationInSeconds) {
            print(date)
        }
}

Что я ожидаю отвидите на моей консоли?

2014-01-01
2014-01-02
2014-01-03
.........
2019-03-30
2019-03-31

1 Ответ

2 голосов
/ 31 марта 2019

Ваш код не компилируется, потому что вы шагаете по целым числам, но вы определили свой Stride как TimeInterval.Если бы вы исправили тип dayDurationInSeconds:

let dayDurationInSeconds: TimeInterval = 60*60*24

, это сделало бы большую часть того, что вы ожидали. Но это даст вам совершенно неверные результаты, потому что не каждый день длится 86 400 секунд.DST изменяет продолжительность дня два раза в год в зависимости от местоположения.

Правильный способ вычисления даты - с Calendar.Если вы не используете Calendar, вы не можете использовать ничего, что явно не выражено в секундах.

То, что вы можете захотеть, - это что-то вроде этого, которое перечисляет все ночи (UTC) междудаты в вопросе.Помните, что Date в Foundation - это не «свидание».Это точный момент времени.Если вы действительно хотите работать с «датами», вам нужны DateComponents.

let formatter = DateFormatter()
formatter.dateFormat = "yyyy/MM/dd"
let startDate = formatter.date(from: "2014/01/01")!
let endDate = formatter.date(from: "2019/03/31")!

var calendar = Calendar(identifier: .gregorian)
calendar.timeZone = TimeZone(identifier: "UTC")!

calendar.enumerateDates(startingAfter: startDate,
                        matching: DateComponents(hour: 0, minute: 0, second:0),
                        matchingPolicy: .nextTime) { (date, _, stop) in
                            guard let date = date, date < endDate else {
                                stop = true
                                return
                            }

                            print(date)
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...