错误的触发日期 UILocalNotification - 触发日期提前一小时

Wrong fire date UILocalNotification - fire date is one hour ahead

我想将 UILocalNotification 设置为在特定时间关闭。该应用程序处理餐厅预订。如果进行了预订并且约会距离现在超过 2 小时,那么我想在它之前 2 小时显示通知。如果它大于 1 小时,那么我要在手前 1 小时显示它,否则我想在手前 15 分钟显示它。我遇到的困难是我的 UILocalNotification 触发时间错误 + 1 hour。下面是使用的代码:

[self setLocalNotificationWithAlertBody:@"Alert Body goes here" AndWithBookingDateString:@"2015-09-07 19:45:00"];//the booking time



-(void)setLocalNotificationWithAlertBody:(NSString *)body AndWithBookingDateString:(NSString *)dateString{

    NSLog(@"Date String %@",dateString);
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    [dateFormatter setTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"GMT"]];
    [dateFormatter setLocale:[[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"]];
    [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
    NSDate *dateFromString = [[NSDate alloc] init];

    dateFromString = [dateFormatter dateFromString:dateString];
    NSLog(@"Date from String %@",[dateFormatter dateFromString:dateString]);

    [self setLocalNotificationWithAlertBody:body AndWithBookingDate:dateFromString];
}



 -(void)setLocalNotificationWithAlertBody: (NSString *) body AndWithBookingDate: (NSDate *)date{

    NSDate *currentDate = [NSDate date];

    NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
    NSDateComponents *components = [calendar components:NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit|NSHourCalendarUnit
                                           fromDate:currentDate
                                             toDate:date
                                            options:0];


    UILocalNotification* localNotification = [[UILocalNotification alloc] init];
    NSInteger hour = [components hour];


    if (components.hour>=2) {//remind the user 2 hours before hand if booking is made greater than 2 hours


        NSTimeInterval secondsPerHour = (60 * 60)*2;//two hours before appointment
        NSDate *givenDate = date; // what you have already
        NSDate *earlierDate = [givenDate dateByAddingTimeInterval:-secondsPerHour];
         NSLog(@"\n\n Greater than 2 hours %@ \n\n",earlierDate);
        localNotification.fireDate=earlierDate;
        localNotification.alertBody = [NSString stringWithFormat:@"%@ %@",body,[self getDeviceShortDateFromString:[NSString stringWithFormat:@"%@",date] WithFormat:@"yyyy-MM-dd HH:mm:ss ZZZZZ"]];
    }
    else if (components.hour>1) {

        NSTimeInterval secondsPerHour = 60 * 60;
        NSDate *givenDate = date; // what you have already
        NSDate *earlierDate = [givenDate dateByAddingTimeInterval:-secondsPerHour];
        NSLog(@"\n\n Greater than an hour %@ \n\n",earlierDate);
        localNotification.fireDate=earlierDate;
        localNotification.alertBody = [NSString stringWithFormat:@"%@ %@",body,[self getDeviceShortDateFromString:[NSString stringWithFormat:@"%@",date] WithFormat:@"yyyy-MM-dd HH:mm:ss ZZZZZ"]];

    }
    else{


        NSTimeInterval secondsPer15mins = 15 * 60;
        NSDate *givenDate = date; // what you have already
        NSDate *earlierDate = [givenDate dateByAddingTimeInterval:-secondsPer15mins];
         NSLog(@"\n\n Less than one hour %@ \n",earlierDate);


        localNotification.fireDate=earlierDate;
        localNotification.alertBody = [NSString stringWithFormat:@"%@ %@",body,[self getDeviceShortDateFromString:[NSString stringWithFormat:@"%@",date] WithFormat:@"yyyy-MM-dd HH:mm:ss ZZZZZ"]];


    }


    localNotification.userInfo = @{@"key" : body};
    [[UIApplication sharedApplication] scheduleLocalNotification:localNotification];

    NSLog(@"Fire date %@",localNotification.fireDate);

    NSLog(@"Notification--->: %@", localNotification);


}


  -(NSString *)getDeviceShortDateFromString: (NSString *) date WithFormat: (NSString *)format{


    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    [dateFormatter setLocale:[[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"]];
    [dateFormatter setDateFormat:format];

    NSDate * tempDate =[dateFormatter dateFromString: date];

    NSDateFormatter *dateFormatter2 = [[NSDateFormatter alloc] init];
    [dateFormatter2 setDateFormat:@"MMM yyyy"];
    if (tempDate == nil) {
        return @" ";
    }

    return [dateFormatter2 stringFromDate:tempDate];

}

开火日期记录为:

Fire date 2015-09-07 17:45:00 +0000

但是本地通知错误:

Notification--->: <UIConcreteLocalNotification: 0x174178300>{fire date = Monday 7 September 2015 18:45:00 Irish Summer Time, time zone = (null), repeat interval = 0, repeat count = UILocalNotificationInfiniteRepeatCount, next fire date = Monday 7 September 2015 18:45:00 Irish Summer Time, user info = {
key = "Alert Body Goes here";
}}

预约时间超过 2 小时,因此通知应该在 5:45 发出,但直到 6:45 才发出。非常感谢任何帮助。

"Help me Whosebug, you're my only hope":)

对于依赖于特定位置结果的可缩放应用,请确保您的特定位置属性始终指向用户的相对位置。在你的例子中,你只是忽略了一个简单的设置:

[dateFormatter setTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"GMT"]];

对你来说,这是 +1 小时,但对其他人来说,它会有所不同,有些会提前,有些会落后,因为你的 fireDate 是基于 GMT 时间。

我只想将其更改为 [NSTimeZone systemTimeZone]