enumerateDates несоответствие при перечислении в обратном порядке? - PullRequest
1 голос
/ 14 января 2020

Странное расхождение происходит между перечислением дня месяца между двумя датами вперед или назад. Я получаю правильный ответ при перечислении вперед, но enumerateDates необъяснимо переходит при перечислении назад.

Давайте попробуем перечислить даты между 2020 и 1980:

let cal = Calendar.current
var dateComponents = DateComponents()
dateComponents.year = 1980
dateComponents.month = 1
dateComponents.day = 1
dateComponents.timeZone = TimeZone(abbreviation: "CET")
dateComponents.hour = 8
dateComponents.minute = 0
let stopDate = cal.date(from: dateComponents)
dateComponents.year = 2020
dateComponents.month = 1
dateComponents.day = 1
let startDate = cal.date(from: dateComponents)
if let stopDate = stopDate {
    if let startDate = startDate {
        var comps = DateComponents()

        //Lets enumerate forward first

        print("Enumerating forward")
        for dotm in 1..<32 {
            var counter = 0
            comps.day = dotm
            comps.hour = 8
            cal.enumerateDates(startingAfter: stopDate, matching: comps, matchingPolicy: .strict, repeatedTimePolicy: .first, direction: .forward) { (date, match, stop) in
                if let date = date {
                    counter += 1
                    if date > startDate {
                        print("number of months with day \(dotm) in month: \(counter)")
                        counter = 0
                        stop = true
                    }
                }
            }
        }

        //And do the same thing backward

        print("Enumerating backward")
        for dotm in 1..<32 {
            var counter = 0
            comps.day = dotm
            comps.hour = 8
            cal.enumerateDates(startingAfter: startDate, matching: comps, matchingPolicy: .strict, repeatedTimePolicy: .first, direction: .backward) { (date, match, stop) in
                if let date = date {
                    counter += 1
                    if date < stopDate {
                        print("number of months with day \(dotm) in month: \(counter)")
                        counter = 0
                        stop = true
                    }
                }
            }
        }

        //Lets inspect closer

        print("What is happening?")
        comps.day = 1
        cal.enumerateDates(startingAfter: startDate, matching: comps, matchingPolicy: .strict, repeatedTimePolicy: .first, direction: .backward) { (date, match, stop) in
            if let date = date {
                print("Date found: \(date)")
                if date < stopDate {
                    stop = true
                }
            }
        }
    }
}

Вывод этого кода:

Enumerating forward
number of months with day 1 in month: 481
number of months with day 2 in month: 481
number of months with day 3 in month: 481
number of months with day 4 in month: 481
number of months with day 5 in month: 481
number of months with day 6 in month: 481
number of months with day 7 in month: 481
number of months with day 8 in month: 481
number of months with day 9 in month: 481
number of months with day 10 in month: 481
number of months with day 11 in month: 481
number of months with day 12 in month: 481
number of months with day 13 in month: 481
number of months with day 14 in month: 481
number of months with day 15 in month: 481
number of months with day 16 in month: 481
number of months with day 17 in month: 481
number of months with day 18 in month: 481
number of months with day 19 in month: 481
number of months with day 20 in month: 481
number of months with day 21 in month: 481
number of months with day 22 in month: 481
number of months with day 23 in month: 481
number of months with day 24 in month: 481
number of months with day 25 in month: 481
number of months with day 26 in month: 481
number of months with day 27 in month: 481
number of months with day 28 in month: 481
number of months with day 29 in month: 451
number of months with day 30 in month: 441
number of months with day 31 in month: 281
Enumerating backward
number of months with day 1 in month: 189
number of months with day 2 in month: 189
number of months with day 3 in month: 189
number of months with day 4 in month: 189
number of months with day 5 in month: 189
number of months with day 6 in month: 189
number of months with day 7 in month: 189
number of months with day 8 in month: 189
number of months with day 9 in month: 189
number of months with day 10 in month: 189
number of months with day 11 in month: 189
number of months with day 12 in month: 189
number of months with day 13 in month: 189
number of months with day 14 in month: 189
number of months with day 15 in month: 189
number of months with day 16 in month: 189
number of months with day 17 in month: 189
number of months with day 18 in month: 189
number of months with day 19 in month: 189
number of months with day 20 in month: 189
number of months with day 21 in month: 189
number of months with day 22 in month: 189
number of months with day 23 in month: 189
number of months with day 24 in month: 189
number of months with day 25 in month: 189
number of months with day 26 in month: 189
number of months with day 27 in month: 189
number of months with day 28 in month: 189
number of months with day 29 in month: 177
number of months with day 30 in month: 174
number of months with day 31 in month: 111
What is happening?
Date found: 2019-12-01 07:00:00 +0000
Date found: 2019-11-01 07:00:00 +0000
Date found: 2019-10-01 06:00:00 +0000
Date found: 1995-09-01 06:00:00 +0000
Date found: 1995-08-01 06:00:00 +0000
Date found: 1995-07-01 06:00:00 +0000
Date found: 1995-06-01 06:00:00 +0000
Date found: 1995-05-01 06:00:00 +0000
Date found: 1995-04-01 06:00:00 +0000
Date found: 1995-03-01 07:00:00 +0000
Date found: 1995-02-01 07:00:00 +0000
Date found: 1995-01-01 07:00:00 +0000
Date found: 1994-12-01 07:00:00 +0000
Date found: 1994-11-01 07:00:00 +0000
Date found: 1994-10-01 07:00:00 +0000
Date found: 1994-09-01 06:00:00 +0000
Date found: 1994-08-01 06:00:00 +0000
Date found: 1994-07-01 06:00:00 +0000
Date found: 1994-06-01 06:00:00 +0000
Date found: 1994-05-01 06:00:00 +0000
Date found: 1994-04-01 06:00:00 +0000
Date found: 1994-03-01 07:00:00 +0000
Date found: 1994-02-01 07:00:00 +0000
Date found: 1994-01-01 07:00:00 +0000
Date found: 1993-12-01 07:00:00 +0000
Date found: 1993-11-01 07:00:00 +0000
Date found: 1993-10-01 07:00:00 +0000
Date found: 1993-09-01 06:00:00 +0000
Date found: 1993-08-01 06:00:00 +0000
Date found: 1993-07-01 06:00:00 +0000
Date found: 1993-06-01 06:00:00 +0000
Date found: 1993-05-01 06:00:00 +0000
Date found: 1993-04-01 06:00:00 +0000
Date found: 1993-03-01 07:00:00 +0000
Date found: 1993-02-01 07:00:00 +0000
Date found: 1993-01-01 07:00:00 +0000
Date found: 1992-12-01 07:00:00 +0000
Date found: 1992-11-01 07:00:00 +0000
Date found: 1992-10-01 07:00:00 +0000
Date found: 1992-09-01 06:00:00 +0000
Date found: 1992-08-01 06:00:00 +0000
Date found: 1992-07-01 06:00:00 +0000
Date found: 1992-06-01 06:00:00 +0000
Date found: 1992-05-01 06:00:00 +0000
Date found: 1992-04-01 06:00:00 +0000
Date found: 1992-03-01 07:00:00 +0000
Date found: 1992-02-01 07:00:00 +0000
Date found: 1992-01-01 07:00:00 +0000
Date found: 1991-12-01 07:00:00 +0000
Date found: 1991-11-01 07:00:00 +0000
Date found: 1991-10-01 07:00:00 +0000
Date found: 1991-09-01 06:00:00 +0000
Date found: 1991-08-01 06:00:00 +0000
Date found: 1991-07-01 06:00:00 +0000
Date found: 1991-06-01 06:00:00 +0000
Date found: 1991-05-01 06:00:00 +0000
Date found: 1991-04-01 06:00:00 +0000
Date found: 1991-03-01 07:00:00 +0000
Date found: 1991-02-01 07:00:00 +0000
Date found: 1991-01-01 07:00:00 +0000
Date found: 1990-12-01 07:00:00 +0000
Date found: 1990-11-01 07:00:00 +0000
Date found: 1990-10-01 07:00:00 +0000
Date found: 1990-09-01 06:00:00 +0000
Date found: 1990-08-01 06:00:00 +0000
Date found: 1990-07-01 06:00:00 +0000
Date found: 1990-06-01 06:00:00 +0000
Date found: 1990-05-01 06:00:00 +0000
Date found: 1990-04-01 06:00:00 +0000
Date found: 1990-03-01 07:00:00 +0000
Date found: 1990-02-01 07:00:00 +0000
Date found: 1990-01-01 07:00:00 +0000
Date found: 1989-12-01 07:00:00 +0000
Date found: 1989-11-01 07:00:00 +0000
Date found: 1989-10-01 07:00:00 +0000
Date found: 1989-09-01 06:00:00 +0000
Date found: 1989-08-01 06:00:00 +0000
Date found: 1989-07-01 06:00:00 +0000
Date found: 1989-06-01 06:00:00 +0000
Date found: 1989-05-01 06:00:00 +0000
Date found: 1989-04-01 06:00:00 +0000
Date found: 1989-03-01 07:00:00 +0000
Date found: 1989-02-01 07:00:00 +0000
Date found: 1989-01-01 07:00:00 +0000
Date found: 1988-12-01 07:00:00 +0000
Date found: 1988-11-01 07:00:00 +0000
Date found: 1988-10-01 07:00:00 +0000
Date found: 1988-09-01 06:00:00 +0000
Date found: 1988-08-01 06:00:00 +0000
Date found: 1988-07-01 06:00:00 +0000
Date found: 1988-06-01 06:00:00 +0000
Date found: 1988-05-01 06:00:00 +0000
Date found: 1988-04-01 06:00:00 +0000
Date found: 1988-03-01 07:00:00 +0000
Date found: 1988-02-01 07:00:00 +0000
Date found: 1988-01-01 07:00:00 +0000
Date found: 1987-12-01 07:00:00 +0000
Date found: 1987-11-01 07:00:00 +0000
Date found: 1987-10-01 07:00:00 +0000
Date found: 1987-09-01 06:00:00 +0000
Date found: 1987-08-01 06:00:00 +0000
Date found: 1987-07-01 06:00:00 +0000
Date found: 1987-06-01 06:00:00 +0000
Date found: 1987-05-01 06:00:00 +0000
Date found: 1987-04-01 06:00:00 +0000
Date found: 1987-03-01 07:00:00 +0000
Date found: 1987-02-01 07:00:00 +0000
Date found: 1987-01-01 07:00:00 +0000
Date found: 1986-12-01 07:00:00 +0000
Date found: 1986-11-01 07:00:00 +0000
Date found: 1986-10-01 07:00:00 +0000
Date found: 1986-09-01 06:00:00 +0000
Date found: 1986-08-01 06:00:00 +0000
Date found: 1986-07-01 06:00:00 +0000
Date found: 1986-06-01 06:00:00 +0000
Date found: 1986-05-01 06:00:00 +0000
Date found: 1986-04-01 06:00:00 +0000
Date found: 1986-03-01 07:00:00 +0000
Date found: 1986-02-01 07:00:00 +0000
Date found: 1986-01-01 07:00:00 +0000
Date found: 1985-12-01 07:00:00 +0000
Date found: 1985-11-01 07:00:00 +0000
Date found: 1985-10-01 07:00:00 +0000
Date found: 1985-09-01 06:00:00 +0000
Date found: 1985-08-01 06:00:00 +0000
Date found: 1985-07-01 06:00:00 +0000
Date found: 1985-06-01 06:00:00 +0000
Date found: 1985-05-01 06:00:00 +0000
Date found: 1985-04-01 06:00:00 +0000
Date found: 1985-03-01 07:00:00 +0000
Date found: 1985-02-01 07:00:00 +0000
Date found: 1985-01-01 07:00:00 +0000
Date found: 1984-12-01 07:00:00 +0000
Date found: 1984-11-01 07:00:00 +0000
Date found: 1984-10-01 07:00:00 +0000
Date found: 1984-09-01 06:00:00 +0000
Date found: 1984-08-01 06:00:00 +0000
Date found: 1984-07-01 06:00:00 +0000
Date found: 1984-06-01 06:00:00 +0000
Date found: 1984-05-01 06:00:00 +0000
Date found: 1984-04-01 06:00:00 +0000
Date found: 1984-03-01 07:00:00 +0000
Date found: 1984-02-01 07:00:00 +0000
Date found: 1984-01-01 07:00:00 +0000
Date found: 1983-12-01 07:00:00 +0000
Date found: 1983-11-01 07:00:00 +0000
Date found: 1983-10-01 07:00:00 +0000
Date found: 1983-09-01 06:00:00 +0000
Date found: 1983-08-01 06:00:00 +0000
Date found: 1983-07-01 06:00:00 +0000
Date found: 1983-06-01 06:00:00 +0000
Date found: 1983-05-01 06:00:00 +0000
Date found: 1983-04-01 06:00:00 +0000
Date found: 1983-03-01 07:00:00 +0000
Date found: 1983-02-01 07:00:00 +0000
Date found: 1983-01-01 07:00:00 +0000
Date found: 1982-12-01 07:00:00 +0000
Date found: 1982-11-01 07:00:00 +0000
Date found: 1982-10-01 07:00:00 +0000
Date found: 1982-09-01 06:00:00 +0000
Date found: 1982-08-01 06:00:00 +0000
Date found: 1982-07-01 06:00:00 +0000
Date found: 1982-06-01 06:00:00 +0000
Date found: 1982-05-01 06:00:00 +0000
Date found: 1982-04-01 06:00:00 +0000
Date found: 1982-03-01 07:00:00 +0000
Date found: 1982-02-01 07:00:00 +0000
Date found: 1982-01-01 07:00:00 +0000
Date found: 1981-12-01 07:00:00 +0000
Date found: 1981-11-01 07:00:00 +0000
Date found: 1981-10-01 07:00:00 +0000
Date found: 1981-09-01 06:00:00 +0000
Date found: 1981-08-01 06:00:00 +0000
Date found: 1981-07-01 06:00:00 +0000
Date found: 1981-06-01 06:00:00 +0000
Date found: 1981-05-01 06:00:00 +0000
Date found: 1981-04-01 06:00:00 +0000
Date found: 1981-03-01 07:00:00 +0000
Date found: 1981-02-01 07:00:00 +0000
Date found: 1981-01-01 07:00:00 +0000
Date found: 1980-12-01 07:00:00 +0000
Date found: 1980-11-01 07:00:00 +0000
Date found: 1980-10-01 07:00:00 +0000
Date found: 1980-09-01 06:00:00 +0000
Date found: 1980-08-01 06:00:00 +0000
Date found: 1980-07-01 06:00:00 +0000
Date found: 1980-06-01 06:00:00 +0000
Date found: 1980-05-01 06:00:00 +0000
Date found: 1976-04-01 07:00:00 +0000

При обратном отсчете происходит странный скачок с 2019 по 1995 и снова с 1980 по 1976. Я что-то не так делаю или это ошибка в enumerateDares? Я использую Xcode 11.3.

Обновление:

Поведение enumerateDates при перечислении в обратном порядке еще более странно. Когда мы меняем startDate, счет иногда бывает правильным. Быстрая проверка всех возможных начальных дней в январе 2020 года дает нам следующую матрицу (первый столбец - startDate, второй столбец - количество дней с dateComponents.day = 1, третий столбец dateComponents.day = 2, et c ...)

2020-01-01 189 189 189 189 189 189 189 189 189 189 189 189 189 189 189 189 189 189 189 189 189 189 189 189 189 189 189 189 177 174 111
2020-01-02 482 189 189 189 189 189 189 189 189 189 189 189 189 189 189 189 189 189 189 189 189 189 189 189 189 189 189 189 177 174 111
2020-01-03 482 482 189 189 189 189 189 189 189 189 189 189 189 189 189 189 189 189 189 189 189 189 189 189 189 189 189 189 177 174 111
2020-01-04 482 482 482 189 189 189 189 189 189 189 189 189 189 189 189 189 189 189 189 189 189 189 189 189 189 189 189 189 177 174 111
2020-01-05 482 482 482 482 189 189 189 189 189 189 189 189 189 189 189 189 189 189 189 189 189 189 189 189 189 189 189 189 177 174 111
...
2020-01-27 482 482 482 482 482 482 482 482 482 482 482 482 482 482 482 482 482 482 482 482 482 482 482 482 482 482 189 189 177 174 111
2020-01-28 482 482 482 482 482 482 482 482 482 482 482 482 482 482 482 482 482 482 482 482 482 482 482 482 482 482 482 189 177 174 111
2020-01-29 482 482 482 482 482 482 482 482 482 482 482 482 482 482 482 482 482 482 482 482 482 482 482 482 482 482 482 201 177 174 111
2020-01-30 482 482 482 482 482 482 482 482 482 482 482 482 482 482 482 482 482 482 482 482 482 482 482 482 482 482 482 201 189 174 111
2020-01-31 482 482 482 482 482 482 482 482 482 482 482 482 482 482 482 482 482 482 482 482 482 482 482 482 482 482 482 201 189 174 111

Так, может быть, enumerateDates правильно рассчитывает, только если первое попадание в текущем месяце?

1 Ответ

1 голос
/ 14 января 2020

Это ошибка, которая возникает всегда после того, как дата установлена ​​на 1 октября.

Пожалуйста, сообщите об ошибке, как я это сделал несколько недель go, к сожалению, Apple еще не ответила.

...