我有一个uilocalnotification对象,我设置了重复间隔日,周和月。我完全没有麻烦来访问对象的火日期:

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

但是我遇到了下一个火灾日期的麻烦。如果我打印出上述通知1对象到控制台的对象,我会明白:

<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}

该对象包含我需要显示下一个火灾日期的值或数据的位置...但是我找不到它!有人知道我可以通过编程方式得到它吗?

谢谢

有帮助吗?

解决方案

我不认为下一个火日期可作为财产可用,而是根据 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 反而。

其他提示

计算 下一个 重复的火日期 UILocalNotification, , 你必须:

  1. 弄清楚的数量 repeatInterval 通知的原始火日期之间已经存在(即 fireDate 属性)和现在。
  2. 将它们添加到通知的 fireDate.

这是一种方法:

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在2:00 pm 01/01
  • 通知 repeatIntervalNSDayCalendaryUnit (即每天重复)
  • 现在的日期是下午3:00的08/01

上述代码将计算为7天(01/01 + 7天= 08/01),将它们添加到 fireDate, ,因此设定 nextFireDate08/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];
}

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

我只会添加repotiNterval,直到将来日期为止:

-(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;
    }

这是 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)
    }

}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top