【问题标题】:How to get the right date from UIDatePicker for Local Notification如何从 UIDatePicker 获取正确的本地通知日期
【发布时间】:2015-11-09 20:53:33
【问题描述】:
- (IBAction)addReminder:(id)sender {
    NSCalendar *calendar = [NSCalendar autoupdatingCurrentCalendar];
    NSDate *date = [self.datePicker date];
    //break date up:
    NSDateComponents *dateComps = [calendar components:NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay fromDate:date];
    NSDateComponents *timeComps = [calendar components:NSCalendarUnitHour |NSCalendarUnitMinute |NSCalendarUnitSecond fromDate:date];
    //set the fire time:
    NSDateComponents *notificationDayComps = [[NSDateComponents alloc] init];
    [notificationDayComps setDay:[dateComps day]];
    [notificationDayComps setMonth:[dateComps month]];
    [notificationDayComps setYear:[dateComps year]];
    [notificationDayComps setHour:[timeComps hour]];
    [notificationDayComps setMinute:[timeComps minute]];
    [notificationDayComps setSecond:[timeComps second]];
    NSDate *notificationDate = [calendar dateFromComponents:notificationDayComps];
    NSLog(@"Setting a reminder for %@", notificationDate);
    UILocalNotification *note = [[UILocalNotification alloc] init];
    if (note == nil) return;
    note.alertBody = @"Hypnotize me!";
    note.fireDate = notificationDate;
    note.timeZone = [NSTimeZone defaultTimeZone];
    //schedule the notification:
    [[UIApplication sharedApplication] scheduleLocalNotification:note];
}

这是我的代码。我正在阅读 Big Nerd Ranch 的书。最初他们告诉我这样做:

- (IBAction)addReminder:(id)sender {
    NSDate *date = self.datePicker.date;
    NSLog(@"Setting a reminder for %@", date);
}

当我点击在这两种方法上触发代码的按钮时,记录的日期不是同一个日期。如果我使用当前语言环境记录它,它会打印正确的日期,但是当我在 iphone 上测试它时,它不会使用正确的日期进行提醒。我尝试在上面添加日历组件,并尝试了此处和其他站点的许多其他提示,但无法让它记录正确的日期或为本地通知设置正确的日期。

2015-11-09 12:42:55.415 HypnoNerd[1251:83127] Setting a reminder for 2015-11-09 20:43:00 +0000

当我在日期选择器上选择今天 12:42 时,就会出现这种情况,但显然它记录了错误的日期。我知道 NSDate 与典型的日历日期不同,但我仍然无法弄清楚如何进行这项工作,因此任何见解都会很棒。谢谢

【问题讨论】:

  • 当你说“不是同一个日期”时,你期待什么日期?
  • 好吧,我在日期选择器上选择了 12:42,但是为本地通知记录和设置的日期是 20:43。你可以在上面看到我展示 NSLog 的地方。我希望能够向从日期选择器中选择的确切日期发送本地通知,但它们不匹配,我不确定引擎盖下发生了什么。谢谢
  • 你的选择器有时区吗?
  • 即使我将日期选择器的时区设置为默认时区,我也会得到相同的结果

标签: ios objective-c date


【解决方案1】:
- (IBAction)addReminder:(id)sender {
    self.datePicker.timeZone = [NSTimeZone defaultTimeZone];
    NSDate *date = [self.datePicker date];
    UILocalNotification *note = [[UILocalNotification alloc] init];
    note.alertBody = @"Hypnotize me!";
    note.fireDate = date;
    note.timeZone = [NSTimeZone defaultTimeZone];
    //schedule the notification:
    UIApplication *app = [UIApplication sharedApplication];
    UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeAlert) categories:nil];
    [app registerUserNotificationSettings:settings];
    [app scheduleLocalNotification:note];
}

这可行,但我真的不明白发生了什么。如果有人能在更一般的意义上解释这个过程,我将不胜感激。感谢您的帮助。

【讨论】:

    【解决方案2】:

    您需要将日期选择器日期转换为本地时区。

    默认它有 UTC 时区。使用下面的代码获取当前日期。

    NSDateFormatter *userFormatter = [[NSDateFormatter alloc] init];
    [userFormatter setTimeZone:[NSTimeZone localTimeZone]];
    [userFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss.SSS"];
    NSString *dateConverted = [userFormatter stringFromDate:self.Datepick.date];
    NSLog(@"%@",dateConverted);
    

    【讨论】:

      【解决方案3】:

      “这些不是你要找的机器人。”

      我认为 OP 的问题是本地通知没有被触发,错误的结论是这与时区设置有关。内部时间以 GMT(又名“UTC”)报告。我们可以在发布的日志消息中看到这一点:

       2015-11-09 20:43:00 +0000
      

      +0000 表示时间尚未从 GMT 偏移+-。无需将此时间报告为当地时间。事实上,没有必要搞乱任何.timeZone 属性。

      @crypt3c 的后续帖子中解决的问题与以下调用有关:

       UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeAlert) categories:nil]
       [app registerUserNotificationSettings:settings];
      

      从 iOS 8 开始,需要用户授予应用程序接收一种或多种通知类型的权限;未经授权,通知将失败。

      因此,iOS 8 及更高版本的正确代码是:

      - (IBAction)addReminder:(id)sender {
           NSDate *date = [self.datePicker date];
           UILocalNotification *note = [[UILocalNotification alloc] init];
           note.alertBody = @"Hypnotize me!";
           note.fireDate = date;
           //schedule the notification:
           UIApplication *app = [UIApplication sharedApplication];
           UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeAlert) categories:nil];
           [app registerUserNotificationSettings:settings];
           [app scheduleLocalNotification:note];
       }
      

      定义了四个UIUserNotificationTypes

      UIUserNotificationTypeNone
      UIUserNotificationTypeBadge
      UIUserNotificationTypeSound
      UIUserNotificationTypeAlert
      

      有关此主题的更多信息,请参阅 iOS 开发人员库中的 UIUserNotificationSettings Class Reference

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-04-13
        • 1970-01-01
        • 2015-06-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多