Can't fire UILocalNotification on custom time ios objective c - ios

I want to fire NSLocalNotification on my custom time. Ex. 1hour before
appointment time but unable to set it on my custom time.
NSDate *dt1 = [NSDate date]; //2018-07-18 10:41:22 +0000
NSString *datestr = [NSString stringWithFormat:#"%#", [NSDate date]];//2018-07-18 10:42:09 +0000
NSRange range = NSMakeRange(11,5);
NSString *cutstring = 05:00 PM;
By this I add substring to current date and change date in my custom
date.
NSString *newstr = [cutstring substringWithRange:NSMakeRange(0, 5)];
NSString *changed = [datestr stringByReplacingCharactersInRange:range withString:newstr]; //2018-07-18 05:00:09 +0000
By this code I got my custom time '2018-07-18 05:00:09 +0000' on which I want to fire UILocalNotification, But issue is that when I set my custom time with NSLocalNotification it set's on such a random time like 18 July 2018 at 4:19:29 PM
[dateFormatter setDateFormat:#"yyyy-MM-dd HH:mm:ss ZZZ"];
NSDate *fireddate = [dateFormatter dateFromString:changed];
localNotification.fireDate = fireddate;
NSLog(#"%#",fireddate);
localNotification.alertBody = [NSString stringWithFormat:#"You have appointment in 1 hour"];
localNotification.soundName = UILocalNotificationDefaultSoundName;
localNotification.applicationIconBadgeNumber = 1;
localNotification.category = #"ACTIONABLE";
//Received Local Notification:<UIConcreteLocalNotification:
0x6000003887b0>{fire date = Wednesday, 18 July 2018 at 4:19:29 PM
India Standard Time, time zone = (null), repeat interval = 0, repeat
count = UILocalNotificationInfiniteRepeatCount, next fire date =
(null), user info = { }}

I would just create a fire date with NSDateComponents where you can set year, month, hour, minute etc.
Something like this:
NSDateComponents *dateComponents = [[NSDateComponents alloc] init];
dateComponents.calendar = [NSCalendar currentCalendar];
[dateComponents setYear:year];
[dateComponents setMonth:month];
[dateComponents setDay:day];
[dateComponents setHour:hour];
NSDate *fireDate = [dateComponents date];
You can read more about it in this great article
NSDateā€‹Components - NSHipster

Related

How to get time interval for every 30:00(30 minutes) from current time to 10:30 pm

Need help to show the time intervals for every 30 mins, suppose the current time is 11:45 am then
Time intervals should be : 12:00 pm,12:30 pm,01:00 pm,01:30 pm,02:00 pm,02:30 pm......10:30 pm.
NSString *time = #"10.30 pm";
NSDate *date1;
NSDate *date2;
{
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"hh.mm a"];
date1 = [formatter dateFromString:time];
date2 = [formatter dateFromString:[formatter stringFromDate:[NSDate date]]];
}
NSTimeInterval interval = [date1 timeIntervalSinceDate: date2];//[date1 timeIntervalSince1970] - [date2 timeIntervalSince1970];
int hour = interval / 3600;
int minute = (int)interval % 3600 / 60;
NSLog(#"%# %dh %dm", interval<0?#"-":#"+", ABS(hour), ABS(minute));
This code returns me difference of current time and the given time how can I proceed further.
You can do something like,
NSString *startTime = #"02:00 AM";
NSString *endTime = #"11:00 AM";
NSDateFormatter *timeFormat = [[NSDateFormatter alloc] init];
[timeFormat setDateFormat:#"hh:mm a"];
NSDate* fromTime = [timeFormat dateFromString:startTime];
NSDate* toTime = [timeFormat dateFromString:endTime];
NSDate *dateByAddingThirtyMinute ;
NSTimeInterval timeinterval = [toTime timeIntervalSinceDate:fromTime];
NSLog(#"time Int %f",timeinterval/3600);
float numberOfIntervals = timeinterval/3600;
NSLog(#"Start time %f",numberOfIntervals);
for(int iCount = 0;iCount < numberOfIntervals*2 ;iCount ++)
{
dateByAddingThirtyMinute = [fromTime dateByAddingTimeInterval:1800];
fromTime = dateByAddingThirtyMinute;
NSString *formattedDateString;
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"hh:mm a"];
formattedDateString = [dateFormatter stringFromDate:dateByAddingThirtyMinute];
NSLog(#"Time after 30 min %#",formattedDateString);
}
In for loop I have taken numberOfIntervals*2 because time interval is 30 min, so 60/30 = 2 and your datebyAddingThirtyMinute is 1800 because 30 min = 1800 seconds. If you want time after every 10 minutes then it should 60/10 = 6, so it should numberOfIntervals*6. And your datebyAddingThirtyMinute should be [fromTime dateByAddingTimeInterval:600];
Hope this will help :)
The most reliable way (also to consider daylight saving time changes) is to use the date math capabilities of NSCalendar.
Simply adding seconds with dateByAddingTimeInterval is not recommended at all.
NSDate *now = [NSDate date];
NSCalendar *cal = [NSCalendar currentCalendar];
// get minute and hour from now
NSDateComponents *nowComponents = [cal components:NSCalendarUnitHour | NSCalendarUnitMinute fromDate: now];
NSDate *currentDate;
// if current minutes is not exactly 0 or 30 get back to the past half hour
if (nowComponents.minute % 30 != 0) {
NSInteger pastHalfHourIndex = nowComponents.minute / 30;
nowComponents.minute = pastHalfHourIndex * 30;
currentDate = [cal nextDateAfterDate:now matchingHour: nowComponents.hour minute: nowComponents.minute second: 0 options: NSCalendarMatchNextTime | NSCalendarSearchBackwards];
} else {
currentDate = now;
}
NSMutableArray<NSDate *>* dates = [NSMutableArray array];
// loop and add 30 minutes until the end time (10:30 pm) is reached
while (nowComponents.minute != 30 || nowComponents.hour != 22) {
currentDate = [cal dateByAddingUnit:NSCalendarUnitMinute value: 30 toDate: currentDate options: NSCalendarMatchNextTime];
[dates addObject:currentDate];
nowComponents = [cal components:NSCalendarUnitHour | NSCalendarUnitMinute fromDate: currentDate];
}
NSLog(#"%#", dates);
Try this code it works for you
NSDateFormatter *datefrmt = [[NSDateFormatter alloc] init];
[datefrmt setDateFormat:#"hh:mm a"];
NSDate* startingTime = [datefrmt dateFromString:startTime];
NSDate* endingTime = [datefrmt dateFromString:endTime];
NSLog(#"Starting time is %#", startingTime);
NSLog(#"Stop time is %#", endingTime);
NSDate * addingTimeInterval;
addingTimeInterval = [startingTime dateByAddingTimeInterval:1800];
NSLog(#"Required output is %#", addingTimeInterval);
I would first check if the given start time is AM or PM, after doing that, I would find the nearest (rounded up) 30m interval of time and simply add 30m to it and check whether or not I was at the given stop stop time, and if not increment a counter.
You could also add each 30m interval to a list if you wanted to keep track of and return that list to be printed out.
If you get the Start date is current date and time, then the end date is automatically set 30 mins use dateByAddingTimeInterval:, see my example,
NSDate *startDate = [NSDate date];
then set ending date is below code,
currentdate = startDate; //today
endingDate = [startDate dateByAddingTimeInterval:(60*60)/2]; // 60*60 is 1 hour.
this above method automatically calculate current time to end time add 30 minutes.
hope its helpful

How to get days in a week from today in objective c

I am trying to get the days of a week in reference to their date.
Ex.: 14th October is a Wednesday.
I am creating a collection view cell and displaying the date as follows.
In the 14th cell it would display Wednesday, but how to get the next day as Thursday, then Friday...and so on.
I have got todays date and which day it is as follows,
day = [components day];
week = [components month];
year = [components year];
weekday = [components weekday];
NSString *string = [NSString stringWithFormat:#"%ld.%ld.%ld", (long)day, (long)week, (long)year];
NSLog(#"%#",string);
NSDate *todayDate = [NSDate date]; // get today date
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"EEEE"];
NSString *convertedDateString = [dateFormatter stringFromDate:todayDate];// here convert date in
NSLog(#"Today formatted date is %#",convertedDateString);
And i have found this method online, which returns the days in string when you pass the integer, but i am having trouble in this too, not understanding which integer to pass every time so I get different strings.
static inline NSString *stringFromWeekday(int weekday){
static NSString *strings[] = {
#"Sunday",
#"Monday",
#"Tuesday",
#"Wednesday",
#"Thursday",
#"Friday",
#"Saturday",
};
return strings[weekday];
}
You already got everything in place. You should be getting the correct day name in the convertedDateString string. You just have to add 24 hours to your todayDate object and use the dateformatter again to get the next day.
NSDate *todayDate = [NSDate date]; // get today date
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"EEEE"];
NSString *convertedDateString = [dateFormatter stringFromDate:todayDate];// here convert date in
You can get the next day like this.
NSDateComponents *dateComponents = [[NSCalendar currentCalendar] components:(NSDayCalendarUnit | NSMonthCalenderUnit | NSYearCalenderUnit | NSWeekdayCalendarUnit) fromDate:today];
[dateComponents setDay:dateComponents.day+1];
NSDate *nextDay = [dateComponents date];
// Get the day by following same approach in the top
You will get days in a week from today using below code.
NSDate *today = [NSDate date];
NSCalendar *gregorian = [[NSCalendar alloc]
initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *weekdayComponents =
[gregorian components:(NSDayCalendarUnit | NSWeekdayCalendarUnit) fromDate:today];
NSInteger day = [weekdayComponents day];
NSInteger weekday = [weekdayComponents weekday];

Wrong fire date UILocalNotification - fire date is one hour ahead

I want to set a UILocalNotification to go off at a certain time. The app deals with restaurant bookings. If a booking is made and the appointment is greater than 2 hours from now, then I want to show the notification 2 hours before it. If it is greater than 1 hour then I was to show it 1 hour before hand, else I want to show it 15 mins before hand. The dificulty Im having is that my UILocalNotification fire time is wrong by + 1 hour. Below is the code used:
[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];
}
The fire date is logging as:
Fire date 2015-09-07 17:45:00 +0000
But the local notification is wrong:
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";
}}
The appointment was booked greater than 2 hours so the notification should be going off at 5:45 but it doesnt go off until 6:45. Any help is greatly appreciated.
"Help me StackOverflow, you're my only hope" :)
For scaleable apps that rely on location specific results, ensure that your location specific properties always point to the users relative location. In your case, you just overlooked a simple setting:
[dateFormatter setTimeZone:[NSTimeZone timeZoneWithAbbreviation:#"GMT"]];
For you, this is +1 hour, but for others it will vary some will be ahead and some will be behind, because your basing the fireDate on GMT's time.
I would simply alter this to be [NSTimeZone systemTimeZone]

Time Zone causing UILocalNotification to be set for incorrect time

I know this is similar to some other questions, but I cannot seem to get an answer and apply it to my situation and get it to work. I am using an NSDateFormatter to try to schedule an alert for 8:00 AM in the morning, no matter the time zone. Here is my code:
[self scheduleNotificationAtTime:#"08:00 AM"];
and then my method
-(void)scheduleNotificationAtTime:(NSString *)time {
NSDateFormatter *format = [[NSDateFormatter alloc] init];
format.dateFormat = #"HH:mm a MM/dd/yy";
NSString *dateString = [NSString stringWithFormat:#"%# %#",time,self.array[2]];
//self.array[2] = is today's date, so today it is 6/13/14
NSDate *date = [format dateFromString:dateString];
UILocalNotification *lnf = [[UILocalNotification alloc] init];
NSLog(#"Time zone %#",[NSTimeZone systemTimeZone]);
lnf.fireDate = date;
lnf.alertBody = [NSString stringWithFormat:#"%# is today",self.navigationItem.title];
lnf.timeZone = [NSTimeZone localTimeZone];
[[UIApplication sharedApplication] scheduleLocalNotification:lnf];
NSLog(#"%#",lnf);
}
and the log statement at the end is reading
{fire date = Friday, June 13, 2014 at 12:00:00 AM Eastern Daylight Time,
time zone = America/New_York (EDT) offset -14400 (Daylight), repeat interval = 0,
repeat count = UILocalNotificationInfiniteRepeatCount, next fire date = (null), user info = (null)}
so it is 8 hours off! its 12:00 AM instead of 8:00 AM
Try doing
format.dateFormat = #"HH:mm a MM/dd/yy zzz";
NSString *dateString = [NSString stringWithFormat:#"%# %# EDT",time,self.array[2]];
then also
lnf.timeZone = [UITimeZone timeZoneWithName:#"EDT"];
this should keep the time zones in sync.
please try making this change :
lnf.timeZone = [NSTimeZone localTimeZone];
to
lnf.timeZone = [NSTimeZone timeZoneWithName:#"UTC"];

iOS: display time as am/pm

I am new to objective c. I wish to do the following:
Convert 24 hour format to 12 hour and then add +2 to hour and display it like: 4:00 pm
I get the 12 hour format but after adding +2 to it , the time is displayed always as "am", i.e even if it is 4 pm it is displayed as 4 am. Below is my code:
NSDate *now = [NSDate date];
NSDateFormatter *timeFormatter=[[NSDateFormatter alloc]init];
timeFormatter.dateFormat=#"hh:00 a";
NSString *currentHour=[timeFormatter stringFromDate:now ];
lblcurrentHour.text=[NSString stringWithFormat:#"%#",currentHour];
NSLog(#"%#",currentHour);
int hour=[[timeFormatter stringFromDate:now]intValue];
NSDateFormatter *dateFormatter1 = [[NSDateFormatter alloc] init];
dateFormatter1.dateFormat = #"HH:mm";
NSDate *date1 = [dateFormatter1 dateFromString:[NSString stringWithFormat:#"%02d:00",hour+=3]];
dateFormatter1.dateFormat = #"hh:mm a";
lblnextHour.text = [dateFormatter1 stringFromDate:date1]; // prints 4:00 am not pm
How do i solve this? Where am i getting wrong?
If I understand your requirements correctly, you want to take the current time and display the minutes as :00, anchoring to the current hour. Then you want to add two hours and display that time. The following code prints 04:00 AM and 06:00 AM to the console (local time is 0421.)
For calendrical calculations, I would avoid using NSDateFormatter as you are doing when you compute the time two hours from now. There are too many ways that can go astray. For example, what happens when the now time is 2300?
A good reference on calendrical calculations in Cocoa is here
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[])
{
#autoreleasepool {
// use gregorian calendar for calendrical calculations
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
// get current date
NSDate *date = [NSDate date];
NSCalendarUnit units = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit;
units |= NSHourCalendarUnit | NSMinuteCalendarUnit;
NSDateComponents *currentComponents = [gregorian components:units fromDate:date];
// change the minutes to 0
currentComponents.minute = 0;
date = [gregorian dateFromComponents:currentComponents];
// format and display the time
NSDateFormatter *timeFormatter = [[NSDateFormatter alloc] init];
timeFormatter.dateFormat = #"hh:mm a";
NSString *currentTimeString = [timeFormatter stringFromDate:date];
NSLog(#"Current hour = %#",currentTimeString);
// add two hours
NSDateComponents *incrementalComponents = [[NSDateComponents alloc] init];
incrementalComponents.hour = 2;
NSDate *twoHoursLater = [gregorian dateByAddingComponents:incrementalComponents toDate:date options:0];
// format and display new time
NSString *twoHoursLaterStr = [timeFormatter stringFromDate:twoHoursLater];
NSLog(#"Two hours later = %#",twoHoursLaterStr);
}
return 0;
}
Try this:
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"hh:mm:ss a"];
NSLog(#"Today's Date and Time: %#", [formatter stringFromDate:[NSDate date]]);
Output:
Today's Date and Time: 02:43:33 PM

Resources