Question

I am using below piece of code to fire localNotification exactly at 5PM IST. But when log the fireDate, it is not displaying time i wanted. Whether i have gone wrong anywhere?

UILocalNotification *localNotification = [[UILocalNotification alloc] init];
    //localNotification.fireDate = myNewDate;

    NSCalendar *calendar = [NSCalendar currentCalendar];
    NSDateComponents *dateComponents = [[NSDateComponents alloc] init];
    NSDate *currentDate = [NSDate date];
    NSDate *fireDate = nil;

    //[dateComponents setDay:3];  // ...or whatever day.
    [dateComponents setHour:11];
    [dateComponents setMinute:30];

    fireDate = [calendar dateByAddingComponents:dateComponents
                                          toDate:currentDate
                                         options:0];

    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    [formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];

    //Optionally for time zone converstions
    [formatter setTimeZone:[NSTimeZone timeZoneWithName:@"GMT"]];

    NSString *stringFromDate = [formatter stringFromDate:fireDate];


    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
    NSDate *dateFromString = [[NSDate alloc] init];
    dateFromString = [dateFormatter dateFromString:stringFromDate];

    NSLog(@"Fire date : %@",dateFromString);
    [localNotification setFireDate:dateFromString];

My output: Fire date : 2014-07-29 16:48:20 +0000

Was it helpful?

Solution

The reason you're not getting 5PM is that there's nothing in the code that attempts to set the time to 5PM. Instead you have this:

[dateComponents setHour:11];
[dateComponents setMinute:30];

fireDate = [calendar dateByAddingComponents:dateComponents
                                      toDate:currentDate
                                     options:0];

What that gets you is a time 11 hours and 30 minutes into the future. You won't get 5PM unless you happen to run the code at exactly 5:30AM. But the code doesn't mention IST anywhere, so you won't get 5PM in that zone.

It's also confusing what you're doing at the end of the code snippet-- converting fireDate to a string, but then converting that string right back to a date. This serves no purpose.

To get 5PM in a particular time zone you need to do something like the following. This gets the next 5PM in the requested time zone, which might be tomorrow if it's already after 5PM there:

    NSTimeZone *zone = [NSTimeZone timeZoneWithName:@"Asia/Kolkata"];
    NSCalendar *calendar = [NSCalendar currentCalendar];
    [calendar setTimeZone:zone];

    NSInteger targetHour = 17; // 5pm

    NSDate *now = [NSDate date];
    NSInteger componentFlags = NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit|NSHourCalendarUnit;
    NSDateComponents *nowDateComponents = [calendar components:componentFlags fromDate:now];

    if (nowDateComponents.hour >= targetHour) {
        nowDateComponents.day += 1;
    }
    nowDateComponents.hour = targetHour;

    NSDate *targetDate = [calendar dateFromComponents:nowDateComponents];

If you want to print this in a human-readable form, you can do something like the following. But NSDateFormatter is only necessary for presenting the date to the user-- it's not part of getting the desired NSDate.

    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    [formatter setTimeZone:zone];
    [formatter setDateStyle:NSDateFormatterLongStyle];
    [formatter setTimeStyle:NSDateFormatterLongStyle];
    NSString *targetDateString = [formatter stringFromDate:targetDate];
    NSLog(@"Target date: %@", targetDateString);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top