В моем приложении мне нужно получить предыдущие 4 часа ночи, а не 4 часа ночи текущей даты. Например:
March 05, 10:00 am, то я должен ожидать, что вернусь: March 05, 4:00 amMarch 05, 02:00 am, то я должен ожидать, что вернусь: March 04, 4:00 amДля этого я использую Calendar.nextDate. Он работает каждый день месяца, кроме последнего дня каждого месяца.
let components = DateComponents(hour: 4, minute: 0, second: 0)
let date = Calendar.current.date(from: DateComponents(year: 2018,
month: 03,
day: 05,
hour: 13,
minute: 25,
second: 0))!
let result = Calendar.current.nextDate(after: date,
matching: components,
matchingPolicy: .nextTime,
direction: .backward)
Выход:
date = "Mar 5, 2018 at 1:25 PM"
result = "Mar 5, 2018 at 4:00 AM"
let components = DateComponents(hour: 4, minute: 0, second: 0)
let date = Calendar.current.date(from: DateComponents(year: 2018,
month: 03,
day: 31,
hour: 13,
minute: 25,
second: 0))!
let result = Calendar.current.nextDate(after: date,
matching: components,
matchingPolicy: .nextTime,
direction: .backward)
Выход:
date = "Mar 31, 2018 at 1:25 PM"
result = "Mar 30, 2018 at 4:00 AM"
// it should give me this instead: "Mar 31, 2018 at 4:00 AM"
Есть идеи, почему это происходит? это ошибка в коде Apple, я должен сообщить об этом? или я неправильно это использую?
Если это ошибка Apple, есть ли другой способ пока что добиться того, что мне нужно?
Посмотрев исходный код Swift, я заметил, что проблема не в функции Calendar.nextDate(). nextDate() использует Calendar.enumerateDates(), и вот в чем настоящая проблема. Однако я не смог найти исходный код для этой функции.
Это та же ошибка с Calendar.enumerateDates():
let components = DateComponents(hour: 4, minute: 0, second: 0)
let date = Calendar.current.date(from: DateComponents(year: 2018,
month: 03,
day: 31,
hour: 13,
minute: 25,
second: 0))!
Calendar.current.enumerateDates(startingAfter: inputDate,
matching: components,
matchingPolicy: .nextTime,
direction: .backward) { (date, exactMatch, stop) in
let result = date
// result = "Mar 30, 2018 at 4:00 AM"
stop = true
}
Также это аналогичная проблема: Swift Calendar.enumerateDates дает неверный результат при запуске в феврале
Проблема на конец месяца? Используется 31 января, 28 февраля или 30 апреля 2018 г. в 13:35, также выполняется резервное копирование на предыдущий день.
Отличный сыщик!
Очень странно. Разобравшись с stackoverflow.com/questions/49266027/…, я только что обнаружил, что проблема в этом вопросе также появляется только на игровой площадке iOS. На игровой площадке macOS этот код работает должным образом.
@rmaddy, это действительно странно, я думал, что все SDK используют одну и ту же платформу Foundation





Это действительно похоже на ошибку, о которой следует сообщить в Apple. Убедитесь, что вы включили работающее тестовое приложение, демонстрирующее проблему. Примечание, что эта ошибка появляется только в iOS. В macOS (по крайней мере, на игровой площадке macOS) код работает должным образом.
А пока есть довольно простой обходной путь.
Измените свой код, чтобы использовать .forward вместо .backward. Это даст следующую дату вместо предыдущей. Кажется, что в этом направлении нет никаких ошибок. Затем используйте:
Calendar.current.date(byAdding: .day, value: -1, date: result)
чтобы получить желаемый результат, вернувшись на один день назад.
Это странно. Для
4:59 AMвы получите4:00 AMв тот же день, что и результат, но для5:00 AMвы получите4:00 AMнакануне. Понятия не имею, что здесь происходит.