Incorrect `nextTriggerDate()` calculations in UNCalendarNotificationTrigger & `nextDate()` in Date.

Originator:schalin
Number:rdar://32865247 Date Originated:June 20 2017
Status:DUPLICATE OF 27389963 (OPEN) Resolved:No
Product:iOS + SDK Product Version:10.0
Classification:Suggestion Reproducible:Yes
 
Area:
UserNotifications Framework

Summary:
UNCalendarNotificationTrigger does not give accurate `next trigger date` calculations.

Steps to Reproduce:
0.
let us say that our current month is June (someday before 30).

1. TriggerDate in UNCalendarNotificationTrigger
let components = DateComponents(day: 31)
let trigger = UNCalendarNotificationTrigger(dateMatching: target, repeats: true)
print(trigger.nextTriggerDate())

2. NextDate in Date
let components = DateComponents(day: 31)
let next = Calendar.current.nextDate(after: Date(), matching: components, matchingPolicy: .nextTime, repeatedTimePolicy: .first, direction: .forward)
print(next)

3. Negative parameters in DateComponents
let components = DateComponents(day: 1, hour: -24)
let trigger = UNCalendarNotificationTrigger(dateMatching: target, repeats: true)
print(trigger.nextTriggerDate())

Expected Results:
1. Jul 31, 2017, 12:00 AM //since there is no '31' in June.
2. Jul 31, 2017, 12:00 AM //since there is no '31' in June.
3. Jun 30, 2017, 12:00 AM //since it's the last day of June.

Observed Results:
1. Jul 1, 2017, 12:00 AM
2. Jul 1, 2017, 12:00 AM
3. nil

Notes:
For #3,
Traditional date calculation method successfully calculates negative values as follows:

let components = DateComponents(year: 2017, month: 7, day: 1, hour: -24)
let date = Calendar.current.date(from: components)!  // gives: Jun 30, 2017, 12:00 AM

, but not in new iOS10 methods.

Comments


Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!