如何从UILocalNotification对象中获取NEXT开火日期

时间:2010-11-29 05:54:13

标签: iphone date setinterval uilocalnotification

我有一个UILocalNotification对象,我已设置了重复间隔日,周和月。我在访问对象的开火日期时没有任何麻烦:

[cell.detailTextLabel setText:[notification1.fireDate description]];

但我遇到了下一次开火日期的麻烦。如果我将上面的notification1对象打印到控制台,我得到这个:

<UIConcreteLocalNotification: 0x613e060>{fire date = 2010-11-29 03:53:52 GMT, time zone = America/Denver (MST) offset -25200, repeat interval = 16, next fire date = 2010-11-30 03:53:52 GMT}

此对象包含显示下一个开火日期所需的值或数据......但我找不到它!有没有人知道我可以通过编程方式获得它?

由于

4 个答案:

答案 0 :(得分:9)

要计算重复UILocalNotification下一个开火日期,您必须:

  1. 计算通知的原始开火日期(即其repeatInterval属性)与现在之间的fireDate数量。
  2. 将其添加到通知fireDate
  3. 这是一种方法:

    NSCalendar *calendar = [NSCalendar autoupdatingCurrentCalendar];
    
    NSDateComponents *difference = [calendar components:notif.repeatInterval
                                               fromDate:notif.fireDate
                                                 toDate:[NSDate date]
                                                options:0];
    
    NSDate *nextFireDate = [calendar dateByAddingComponents:difference
                                                     toDate:notif.fireDate
                                                    options:0];
    

    这适用于许多场景,但这是一个不起作用的场景:

    假设:

    • 通知的`fireDate是01/01在下午2:00
    • 通知的repeatIntervalNSDayCalendaryUnit(即每日重复)
    • 现在的日期是08/01下午3:00

    以上代码将计算差异为7天(01/01 + 7天= 08/01),将其添加到fireDate,从而将nextFireDate设置为 08/01下午2点。但那是在过去,我们希望nextFireDate 09/01在下午2点

    因此,如果使用上述代码且repeatIntervalNSDayCalendaryUnit,请添加以下行:

    if ([nextFireDate timeIntervalSinceDate:[NSDate date]] < 0) {
        //next fire date should be tomorrow!
        NSDateComponents *extraDay = [[NSDateComponents alloc] init];
        extraDay.day = 1;
        nextFireDate = [calendar dateByAddingComponents:extraDay toDate:nextFireDate options:0];
    }
    

    我将此答案标记为社区维基,如果您找到了更好的计算方法,请随时编辑它!

答案 1 :(得分:7)

我不认为下一个开火日期可用作属性,而是从fireDaterepeatInterval计算得出。对于不同的时区和其他讨厌的事情,日期计算可能会很棘手。在您的示例中,您选择了每日重复并计算下一个开火日期,您可以按照以下方式执行操作:

NSCalendar *calendar = localNotif.repeatCalendar;
if (!calendar) {
  calendar = [NSCalendar currentCalendar];
}

NSDateComponents *components = [[[NSDateComponents alloc] init] autorelease];
components.day = 1;
NSDate *nextFireDate = [calendar dateByAddingComponents:components toDate:localnotif.fireDate options:0];

如果您使用其他重复间隔,则必须相应地更改代码。如果您使用NSMonthCalendarUnit,则必须使用components.month = 1

答案 2 :(得分:0)

我只想添加repeatInterval,直到日期为止:

-(NSDate*)nextFireDateForNotification:(UILocalNotification*)notification {
        NSCalendar *calendar = notification.repeatCalendar;
        if (!calendar) {
            calendar = [NSCalendar currentCalendar];
        }

        NSDate* date = [notification.fireDate copy];
        while (date.timeIntervalSinceNow > 0) {
            date = [calendar dateByAddingUnit:notification.repeatInterval value:1 toDate:date options:0];
        }
        return date;
    }

答案 3 :(得分:0)

它位于 Swift 4 中,并使用日历的nextDate函数。

extension UILocalNotification {

    var nextFireDate: Date? {
        guard let fireDate = fireDate else { return nil }

        let today = Date()
        let cal = Calendar.current

        if fireDate.compare(today) == .orderedDescending {
            return fireDate
        }

        let s: Set<Calendar.Component>
        switch repeatInterval {
        case .year: s = [.month, .day, .hour, .minute, .second]
        case .month: s = [.day, .hour, .minute, .second]
        case .day: s = [.hour, .minute, .second]
        case .hour: s = [.minute, .second]
        case .minute: s = [.second]
        default: return nil // Not supporting other intervals
        }

        let components = cal.dateComponents(s, from: fireDate)
        return cal.nextDate(after: today, matching: components, matchingPolicy: .nextTimePreservingSmallerComponents)
    }

}