【问题标题】:How to grab the NEXT fire date from a UILocalNotification object如何从 UILocalNotification 对象中获取 NEXT 触发日期
【发布时间】:2010-11-29 05:54:12
【问题描述】:

我有一个 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}

这个对象在某处包含我需要显示下一个开火日期的值或数据......但我找不到它!有人知道我可以在哪里以编程方式获得它吗?

谢谢

【问题讨论】:

  • 好吧,我在问了我的问题后看到了,但没有答案……那我该怎么办?
  • 对象明明知道下一次开火日期是什么时候却没有暴露给你,这很令人沮丧。

标签: iphone date setinterval uilocalnotification


【解决方案1】:

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

  1. 算出通知的原始触发日期(即其fireDate 属性)与现在之间的repeatInterval 数量。
  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 是 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];
}

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

【讨论】:

  • 我们可以跳过即将到来的开火日期,而不是处理下一个开火日期吗?并在下一个重复时间继续
  • 这几乎是但不完全 - 看似正确的答案在这里:stackoverflow.com/questions/20926952/…
【解决方案2】:

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

【讨论】:

  • 嘿,非常感谢!我想我现在肯定有一个坚定的方向
  • 这不是一个正确的答案。这只是将一个组件元素添加到通知初始触发日期,它不计算重复通知的发生次数。
  • 为了阻止任何未来的相同性质的编辑建议,请勿编辑此帖子以说它不正确,并插入指向更正确答案的链接。相反,对帖子进行投票并在必要时留下 cmets。
  • @FabrizioProsperi,我看不到提问者在哪里谈论计算通知发生次数。对我来说,这绝对是一个很好且正确的答案。
  • @FabrizioProsperi,好的,我明白你的意思。但对我来说,这 一个很好的答案,因为它肯定会在解决方案的轨道上。好的,这不会“按原样”工作,但稍加思考,我们可以轻松地根据他的答案编写算法。 Stackoverflow 不应该是我们只是将代码复制粘贴到生产应用程序的地方。
【解决方案3】:

我只会添加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;
    }

【讨论】:

    【解决方案4】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-03-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-23
      • 1970-01-01
      • 2011-01-02
      相关资源
      最近更新 更多