Календарь Swift Foundation nextDate () дает странные результаты - PullRequest
0 голосов
/ 26 февраля 2019

Вот что я думаю об ошибке, о которой я сообщил Apple в июне прошлого года (ошибка № 41023217), но не получил ответа.Любые идеи приветствуются.

Резюме:

Сканирование назад и вперед для дат, соответствующих месяцу, дает странные результаты.Прямое сканирование, похоже, неправильно обрабатывает переход на летнее время.Сканирование в обратном направлении приводит к результатам, которые иногда кажутся просто неправильными.

Шаги для воспроизведения:

Запустите swift REPL в терминале и запустите этот код:

import Foundation
var now = Date()
var cal = Calendar.current
var comp = DateComponents()
print("Scanning forward")
for monthNo in 1...12 {
    comp.setValue(monthNo, for: .month)
    let nextDate = cal.nextDate(after: now, matching: comp, matchingPolicy: .strict, repeatedTimePolicy: .first, direction: .forward)
    print("Month: ", monthNo, ", next date: ", nextDate)
}
print("Scanning backward")
for monthNo in 1...12 {
    comp.setValue(monthNo, for: .month)
    let nextDate = cal.nextDate(after: now, matching: comp, matchingPolicy: .strict, repeatedTimePolicy: .first, direction: .backward)
    print("Month: ", monthNo, ", next date: ", nextDate)
}

Ожидаемые результаты:

Следующая дата с соответствующим значением месяца для прямого поиска.Самая последняя дата с соответствующим значением месяца для обратного поиска (или, по крайней мере, начало самого последнего диапазона с соответствующим значением месяца).

Фактические результаты:

Scanning forward
Month:  1 , next date:  Optional(2020-01-01 00:00:00 +0000)
Month:  2 , next date:  Optional(2020-02-01 00:00:00 +0000)
Month:  3 , next date:  Optional(2019-03-01 00:00:00 +0000)
Month:  4 , next date:  Optional(2019-03-31 23:00:00 +0000)
Month:  5 , next date:  Optional(2019-04-30 23:00:00 +0000)
Month:  6 , next date:  Optional(2019-05-31 23:00:00 +0000)
Month:  7 , next date:  Optional(2019-06-30 23:00:00 +0000)
Month:  8 , next date:  Optional(2019-07-31 23:00:00 +0000)
Month:  9 , next date:  Optional(2019-08-31 23:00:00 +0000)
Month:  10 , next date:  Optional(2019-09-30 23:00:00 +0000)
Month:  11 , next date:  Optional(2019-11-01 00:00:00 +0000)
Month:  12 , next date:  Optional(2019-12-01 00:00:00 +0000)
Scanning backward
Month:  1 , next date:  Optional(2019-01-05 00:00:00 +0000)
Month:  2 , next date:  Optional(2018-02-01 01:00:00 +0000)
Month:  3 , next date:  Optional(2018-03-02 23:00:00 +0000)
Month:  4 , next date:  Optional(2018-03-31 23:00:00 +0000)
Month:  5 , next date:  Optional(2018-05-02 23:00:00 +0000)
Month:  6 , next date:  Optional(2018-05-31 23:00:00 +0000)
Month:  7 , next date:  Optional(2018-07-01 23:00:00 +0000)
Month:  8 , next date:  Optional(2018-08-31 22:00:00 +0000)
Month:  9 , next date:  Optional(1970-08-31 23:00:00 +0000)
Month:  10 , next date:  Optional(2018-10-03 00:00:00 +0000)
Month:  11 , next date:  Optional(2018-11-01 00:00:00 +0000)
Month:  12 , next date:  Optional(2018-12-31 23:59:59 +0000)

Ответы [ 2 ]

0 голосов
/ 27 февраля 2019

Вы можете в дальнейшем квалифицироваться DateComponents, и я полагаю, что вы получите значения, которые вы ищете:

var comp = DateComponents(calendar: cal, day: 1, hour: 0, minute: 0, second: 0, nanosecond: 0)

Таким образом:

let formatter = DateFormatter()
formatter.dateStyle = .short
formatter.timeStyle = .short

let now = Date()
let calendar = Calendar.current
var components = DateComponents(calendar: calendar, day: 1, hour: 0, minute: 0, second: 0, nanosecond: 0)

print("Scanning forward")
for monthNo in 1...12 {
    components.setValue(monthNo, for: .month)
    let nextDate = calendar.nextDate(after: now, matching: components, matchingPolicy: .strict, repeatedTimePolicy: .first, direction: .forward)
    print("Month: ", monthNo, ", next date: ", formatter.string(from: nextDate!))
}

print("Scanning backward")
for monthNo in 1...12 {
    components.setValue(monthNo, for: .month)
    let nextDate = calendar.nextDate(after: now, matching: components, matchingPolicy: .strict, repeatedTimePolicy: .first, direction: .backward)
    print("Month: ", monthNo, ", next date: ", formatter.string(from: nextDate!))
}

Производит:

Сканирование впередМесяц: 1, следующая дата: 01.01.20, 12:00Месяц: 2, следующая дата: 1.02.20, 12:00Месяц: 3, следующая дата: 3/1/19, 12:00Месяц: 4, следующая дата: 01.04.19, 12:00Месяц: 5, следующая дата: 5/1/19, 12:00Месяц: 6, следующая дата: 01.06.19, 12:00Месяц: 7, следующая дата: 01.07.19, 12:00Месяц: 8, следующая дата: 8/1/19, 12:00Месяц: 9, следующая дата: 01.09.19, 12:00Месяц: 10, следующая дата: 1.10.19, 12:00Месяц: 11, следующая дата: 01.11.19, 12:00Месяц: 12, следующая дата: 12/1/19, 12:00Сканирование назадМесяц: 1, следующая дата: 01.01.19, 12:00Месяц: 2, следующая дата: 1 февраля 19:00Месяц: 3, следующая дата: 3/1/18, 12:00Месяц: 4, следующая дата: 01.04.18, 12:00Месяц: 5, следующая дата: 5/1/18, 12:00Месяц: 6, следующая дата: 01.06.18, 12:00Месяц: 7, следующая дата: 01.07.18, 12:00Месяц: 8, следующая дата: 01.08.18, 12:00Месяц: 9, следующая дата: 01.09.18, 12:00Месяц: 10, следующая дата: 10/1/18, 12:00Месяц: 11, следующая дата: 01.11.18, 12:00Месяц: 12, следующая дата: 12/1/18, 12:00

0 голосов
/ 26 февраля 2019

Я думаю, что вы злоупотребляете своими политиками соответствия и политиками повторного времени ..

Но если вы хотите, чтобы ваш ожидаемый результат с Calendar, вы можете используйте следующий код :

// Import Foundation to use 'Calendar' and 'Date' classes and structures  
import Foundation

/// Setting the current user calendar
let cal = Calendar.autoupdatingCurrent

/// Saving the current date
let now = Date()

print("Forward scanning... ->")
for i in 1...12 {
    /// Storing result
    let date = cal.date(byAdding: .month, value: i, to: now)
    // Print result
    print("Mounth: \(i), date: \(date!.debugDescription)")
}

print("\nBackward scanning... ->")
for i in 1...12 {
    /// Storing result << please take note of the second argument>>>
    let date = cal.date(byAdding: .month, value: -i, to: now)
    // Print result
    print("Mounth: \(i), date: \(date!.debugDescription)")
}

При использовании date(byAdding: 'Calendar.Component', value: 'Int', to: 'Date') календарь выполняет поиск по смещению буквального месяца

...