Compare NSDate times - ios

I'd like to compare two different times in an if statement. Fort example
if (10:37 > 09:00) // DO SOMETHING
Is there a way to do this using NSDate and NSDateFormatter?

NSDate *date1;
NSDate *date2;
if([date1 laterDate:date2] == *it will return the later date, either date1 or date2*)

Try this
//Date formatter - to format the sample dates using for comparison
NSDateFormatter *dateformatter = [[NSDateFormatter alloc]init];
[dateformatter setDateFormat:#"HH:MM:SS"];
// Creating 2 sample dates
NSDate *date1 = [dateformatter dateFromString:#"10:10:10"];
NSDate *date2 = [dateformatter dateFromString:#"10:10:20"];
if (NSOrderedDescending == [date1 compare:date2])// Here comparing the dates
{
NSLog(#"date1 later than date 2");
}
else
{
NSLog(#"date2 later than date 1");
}

You need to use timeIntervalSinceDate api for comparing two different times.

As I understand your question, you only have times, not dates. Actually than NSDate isn't the best choice, as it represents exactly one moment in time for all eternity.
If you only have times or recurring dates, NSDateComponents are the better choice. You can define what components is used, in your case hour and minute.
NSDateComponents have one caveat: no compare: method, but you can easily compare as
if (date1Comps.hour < date2Comps.hour) {
NSLog(#"date 1 earlier");
} else if(date1Comps.hour > date2Comps.hour) {
NSLog(#"date 2 earlier");
} else {
if (date1Comps.minute < date2Comps.minute) {
NSLog(#"date 1 earlier");
} else if(date1Comps.minute > date2Comps.minute){
NSLog(#"date 2 earlier");
} else {
NSLog(#"same hour, same minute");
}
}
here is the full code including creating components from dates.
NSString *date1String = #"2014-07-18T10:30";
NSString *date2String = #"2014-07-18T10:45";
NSDateFormatter *f = [[NSDateFormatter alloc] init];
[f setDateFormat:#"yyyy-MM-dd'T'HH:mm"];
NSDate *date1 = [f dateFromString:date1String];
NSDate *date2 = [f dateFromString:date2String];
NSDateComponents *date1Comps = [[NSCalendar currentCalendar] components:(NSCalendarUnitHour|NSCalendarUnitMinute) fromDate:date1];
NSDateComponents *date2Comps = [[NSCalendar currentCalendar] components:(NSCalendarUnitHour|NSCalendarUnitMinute) fromDate:date2];
if (date1Comps.hour < date2Comps.hour) {
NSLog(#"date 1 earlier");
} else if(date1Comps.hour > date2Comps.hour) {
NSLog(#"date 2 earlier");
} else {
if (date1Comps.minute < date2Comps.minute) {
NSLog(#"date 1 earlier");
} else if(date1Comps.minute > date2Comps.minute){
NSLog(#"date 2 earlier");
} else {
NSLog(#"same hour, same minute");
}
}
or similar: order the date components in an array
NSArray *times = [#[date1Comps, date2Comps] sortedArrayUsingComparator:^NSComparisonResult(NSDateComponents *date1Comps, NSDateComponents *date2Comps) {
if (date1Comps.hour < date2Comps.hour) {
return NSOrderedAscending;
} else if(date1Comps.hour > date2Comps.hour) {
return NSOrderedDescending;
} else {
if (date1Comps.minute < date2Comps.minute) {
return NSOrderedAscending;
} else if(date1Comps.minute > date2Comps.minute){
return NSOrderedDescending;
}
}
return NSOrderedSame;
}];
You can save this comparison block and reuse it. Than it won't matter much that there is no easy compare method.

NSDateComponents *components = [[NSCalendar currentCalendar] components:NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit fromDate:[NSDate date]];
NSInteger todayHour = [components hour];
NSInteger currentMinute = [components minute];
if (currentHour < 7 || (currentHour > 21 || currentHour == 21 && (currentMinute > 0 || currentMinute > 0))) {
// Do your task
}
This may helps you :)

Related

How to check the date cross the sunday and rest data

How to check the date cross the Sunday and reset the data?
I need to do reset on every Sunday, if I missed that on Sunday then the reset need to happen if user open the app the following increment date(i.e mon,tue, till saturday).
For Every Sunday or crossed the Sunday one time the reset need to happened, if user forgot to open the application on Rest date.
Following the my code which i try to implemented.
Which was not working as per my requirement, Your feedback is highly appreciated.
-(void) weekDaySundayToRefresh
{
NSDate *now = [NSDate date];
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
NSDateComponents *components = [calendar components:NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitWeekOfMonth | NSCalendarUnitWeekday fromDate:now];
NSUInteger weekdayToday = [components weekday];
NSInteger daysToMonday = (8 - weekdayToday) % 7;
nextSunday= [now dateByAddingTimeInterval:60*60*24*daysToSunday];
NSLog(#"nextMonday : %#", nextSunday);
}
-(void) compareDate
{
NSDate *today = [NSDate date]; // it will give you current date
// NSDate *newDate = [MH_USERDEFAULTS objectForKey:#"USER_BACKGROUND_DATE"]; // your date
NSComparisonResult result;
//has three possible values: NSOrderedSame,NSOrderedDescending, NSOrderedAscending
result = [today compare:refreshGoalsDate]; // comparing two dates
if(result==NSOrderedAscending)
{
NSLog(#"today is less");
}
else if(result==NSOrderedDescending)
{
NSLog(#"newDate is less");
NSDate *fromDate;
NSDate *toDate;
NSCalendar *calendar = [NSCalendar currentCalendar];
[calendar rangeOfUnit:NSCalendarUnitDay startDate:&fromDate
interval:NULL forDate:refreshGoalsDate];
[calendar rangeOfUnit:NSCalendarUnitDay startDate:&toDate
interval:NULL forDate:today];
NSDateComponents *difference = [calendar components:NSCalendarUnitDay
fromDate:fromDate toDate:toDate options:0];
noOfDaysCount = [difference day];
NSLog(#"date difference:%ld",(long)[difference day]);
}
else
NSLog(#"Both dates are same");
}
-(void) checkRefreshGoals:(int)sectionIndex rowIndex:(int)rowIndex
{
NSDateFormatter * formatter = [NSDateFormatter new];
[formatter setDateFormat:#"yyyy-MM-dd"];
NSString * currentDateString = [formatter stringFromDate:[NSDate date]];
NSString * initialNotificationDate = [formatter stringFromDate:refreshDate];
NSDate *currentDate = [formatter dateFromString:currentDateString];
NSDate *refreshDate = [formatter dateFromString:initialNotificationDate];
if ([refreshDate compare:currentDate] == NSOrderedDescending)
{
NSLog(#"date1 is later than date2");
isGoalsRefreshed = NO;
}
else if ([refreshDate compare:currentDate] == NSOrderedAscending)
{
NSLog(#"date1 is earlier than date2");
if (sameDay == YES)
{
isGoalsRefreshed = YES;
[self refreshDataOnSunday:sectionIndex rowIndex:rowIndex];
}
else if (noOfDaysCount > 7)
{
isGoalsRefreshed = YES;
[self refreshDataOnSunday:sectionIndex rowIndex:rowIndex];
}
else
{
isGoalsRefreshed = NO;
}
}
else
{
NSLog(#"dates are the same");
isRefreshed = NO;
}
}
-(void) refreshDataOnSunday:(int)sectionIndex rowIndex:(int)rowIndex
{
if (noOfDaysCount > 7)
{
if (isGoalsRefreshed == YES)
{
// Do rest your data
}
}
else if (sameDay == YES)
{
if (isGoalsRefreshed == YES)
{
// Do reset your data
}
}
else
{
isGoalsRefreshed = NO;
}
}
First you need to save todays date and DayNumber when user opens your app at first time and then you need to compare next app open date so you can estimate either Sunday is gone or not.
/*first check in userDefault for stored Date and Day
Store values in local and check with current date */
NSMutableDictionary *dictStoredData = [USERDEFAULT valueForKey:#"dateTimeDate"];
if (!dictStoredData) {
// user comes first time so store it here
dictStoredData =[[NSMutableDictionary alloc] init];
NSDate *today =[NSDate date];
NSCalendar *gregorian =[[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
NSDateComponents *comps =[gregorian components:NSCalendarUnitWeekday fromDate:[NSDate date]];
NSInteger weekday = [comps weekday];
int nextSundayVal = 7 - (int)weekday;
NSDateFormatter *format = [[NSDateFormatter alloc] init];
[format setDateFormat:#"yyyy-MM-dd"];
NSString *startDate = [format stringFromDate: today];
[dictStoredData setObject:startDate forKey:#"startDate"];
[dictStoredData setObject:[NSString stringWithFormat:#"%d",nextSundayVal] forKey:#"nextSundayVal"];
[USERDEFAULT setObject:dictStoredData forKey:#"dateTimeDate"];
}
else{
NSString *strEndDate = #"2017-01-08";
NSString *strStartDate = [dictStoredData valueForKey:#"startDate"];
int nextSundayVal = (int)[dictStoredData valueForKey:#"nextSundayVal"];
NSDateFormatter *format = [[NSDateFormatter alloc] init];
[format setDateFormat:#"yyyy-MM-dd"];
NSDate *startDate = [format dateFromString:strStartDate];
NSDate *endDate = [format dateFromString:strEndDate];
NSCalendar *gregorianCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
NSDateComponents *components = [gregorianCalendar components:NSCalendarUnitDay
fromDate:startDate
toDate:endDate
options:0];
int newDayCount = (int)[components day];
if (newDayCount > nextSundayVal) {
NSLog(#"sunday is gone so reload data!!");
//save this date as a new date and check with this when user come again
}
else {
NSLog(#"sunday is not come yet!!");
}
}
here strEndDate is next date when user opens your application so you can get it from [NSDate date] with same dateformater.
I have run this code in my machine and its printing sunday is gone so reload data so hope this will help you.
As like you we had flow, every friday and more than seven days, its need to update the server.
We did it with following code:
You need to update last updated date.
Check this out:
if ([isFirday isEqualToString:#"Friday"]) {//This is my value from server side (they will give as friay), i think you dont need this condition.
BOOL isSameDay;
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"MMM dd yyyy,HH:mm"];
NSDate *date = [dateFormatter dateFromString:mennuRefreshTime];//Is an last updated date.
[dateFormatter setDateFormat:#"yyyy-MM-dd HH:mm:ss"];
NSString *temp = [dateFormatter stringFromDate:date];
NSDate *lastDate = [dateFormatter dateFromString:temp];
NSString *currentDaystr = [dateFormatter stringFromDate:[NSDate date]];
// Write the date back out using the same format
NSDate *currentDate = [dateFormatter dateFromString:currentDaystr];
if ([lastDate compare:currentDate] == NSOrderedDescending) {
NSLog(#"date1 is later than date2");
isSameDay = NO;
} else if ([lastDate compare:currentDate] == NSOrderedAscending) {
NSLog(#"date1 is earlier than date2");
[dateFormatter setDateFormat:#"EEEE"];
NSString *dayName = [dateFormatter stringFromDate:currentDate];
NSString *lastupdateName = [dateFormatter stringFromDate:lastDate];
if ([dayName isEqualToString:lastupdateName]) {
isSameDay = YES;
}else{
isSameDay = NO;
}
} else {
NSLog(#"dates are the same");
isSameDay = YES;
}
if (isSameDay == YES) {
return;
}
NSCalendar *calender =[[NSCalendar alloc]initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
NSDateComponents *components = [calender components:NSCalendarUnitDay fromDate:lastDate toDate:currentDate options:0];
int day = (int)[components day];
if (day >= 7) {
[self getTopList];
}else{
[dateFormatter setDateFormat:#"EEEE"];
NSString *dayName = [dateFormatter stringFromDate:currentDate];
if ([dayName isEqualToString:isFirday]) {
[self getTopList];
}else{
return;
}
}
}

How to get date and time in format like - [Today 10:01:20], [08-jan-17 11:20:51] etc?

I am working on chat apps and I want to send date/time in particular format like Today, yesterday with date. How can I display according to this format?
- (NSString *)relativeDateStringForDate:(NSDate *)date
{
NSCalendarUnit units = NSCalendarUnitDay | NSCalendarUnitWeekOfYear |
NSCalendarUnitMonth | NSCalendarUnitYear;
NSDateComponents *components = [[NSCalendar currentCalendar] components:units
fromDate:date
toDate:[NSDate date]
options:0];
if (components.year > 0) {
return [NSString stringWithFormat:#"%ld years ago", (long)components.year];
} else if (components.month > 0) {
return [NSString stringWithFormat:#"%ld months ago", (long)components.month];
} else if (components.weekOfYear > 0) {
return [NSString stringWithFormat:#"%ld weeks ago", (long)components.weekOfYear];
} else if (components.day > 0) {
if (components.day > 1) {
return [NSString stringWithFormat:#"%ld days ago", (long)components.day];
} else {
return #"Yesterday";
}
} else
{
return #"Today";
}
}
I am using above function to get date but I want date time in combined string. So how to pass date/time combine to the above method? Is it possible to send a date time string to this method?
For getting the date in format [08-jan-17 11:20:51], you can use the below code
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
// Convert to new Date Format
[dateFormatter setDateFormat:#"dd-MMM-yy HH:mm:ss"];
NSDate *date = [NSDate date];
NSString *newDate = [dateFormatter stringFromDate:date]
NSLog(#"[%#]",newDate); // this will give you the date in format [08-jan-17 11:20:51]
For getting the time in format [10:01:20], you can use the below code
// Convert to new Time Format
[dateFormatter setDateFormat:#"HH:mm:ss"];
NSDate *date = [NSDate date];
NSString *newTime = [dateFormatter stringFromDate:date];
NSLog(#"%#",newTime); // this will give you the time in format 10:01:20
So you can use your code like this -
- (NSString *)relativeDateStringForDate:(NSDate *)date
{
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
// Convert to new Date Format
[dateFormatter setDateFormat:#"dd-MMM-yy HH:mm:ss"];
NSString *newDate = [dateFormatter stringFromDate:date];
NSLog(#"[%#]",newDate);
// Convert to new Time Format
[dateFormatter setDateFormat:#"HH:mm:ss"];
NSString *newTime = [dateFormatter stringFromDate:date];
NSLog(#"%#",newTime);
NSCalendarUnit units = NSCalendarUnitDay | NSCalendarUnitWeekOfYear |
NSCalendarUnitMonth | NSCalendarUnitYear;
NSDateComponents *components = [[NSCalendar currentCalendar] components:units
fromDate:date
toDate:[NSDate date]
options:0];
if (components.year > 0) {
return [NSString stringWithFormat:#"[%ld years ago], [%#]", (long)components.year, newDate];
} else if (components.month > 0) {
return [NSString stringWithFormat:#"[%ld months ago], [%#]", (long)components.month, newDate];
} else if (components.weekOfYear > 0) {
return [NSString stringWithFormat:#"[%ld weeks ago], [%#]", (long)components.weekOfYear, newDate];
} else if (components.day > 0) {
if (components.day > 1) {
return [NSString stringWithFormat:#"[%ld days ago], [%#]", (long)components.day, newDate];
} else {
return [NSString stringWithFormat:#"[Yesterday %#]",newTime];
}
} else
{
return [NSString stringWithFormat:#"[Today %#]", newTime];
}
}
A couple of observations:
You want NSCalendarUnitWeekOfMonth, not NSCalendarUnitWeekOfYear.
In order to distinguish between "today" and "yesterday", you can't just get the date components between two NSDate objects. You should get the date components (but not time components) of the two dates first, and then get the difference between those two sets of date components.
As it is, if it's 9am and you're looking at a message from 11pm last night, it will calculate that day < 1, and thus it will say "Today 11pm" (which is wrong) rather than "Yesterday 11pm".
If you're going to include that "x months ago" string, I'd suggest getting out of the business of building it yourself. Apple has a class that does that for you (NSDateComponentsFormatter) and it's localized.
So, pulling that all together, you get something like:
- (NSString *)relativeDateStringForDate:(NSDate *)date {
// get the number of days differences
NSCalendarUnit units = NSCalendarUnitDay | NSCalendarUnitWeekOfMonth | NSCalendarUnitMonth | NSCalendarUnitYear;
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *dateComponents = [calendar components:units fromDate:date];
NSDateComponents *nowComponents2 = [calendar components:units fromDate:[NSDate date]];
NSDateComponents *components = [calendar components:units fromDateComponents:dateComponents toDateComponents:nowComponents2 options:0];
if (components.year > 0 || components.month > 0 || components.weekOfMonth > 0 || components.day > 1) {
NSDateComponentsFormatter *formatter = [[NSDateComponentsFormatter alloc] init];
formatter.allowedUnits = units;
formatter.maximumUnitCount = 2; // set this to whatever you want, but 1 or 2 is often best
formatter.unitsStyle = NSDateComponentsFormatterUnitsStyleFull;
return [NSString stringWithFormat:#"%# %#", [formatter stringFromDateComponents:components], NSLocalizedString(#"ago", #"x days _ago_")];
} else {
// build time string
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
formatter.timeStyle = NSDateFormatterShortStyle;
NSString *timeString = [formatter stringFromDate:date];
if (components.day == 1) {
return [NSString stringWithFormat:#"%# %#", NSLocalizedString(#"Yesterday", #"day before today"), timeString];
} else {
return [NSString stringWithFormat:#"%# %#", NSLocalizedString(#"Today", #"well, er, today"), timeString];
}
}
}
Now, notice that I excluded the time if the date was before yesterday. The time doesn't make sense if the date string is measured in any units greater than days (e.g. the time is meaningless in this string: "3 months ago, 11:20am"). If you want to include the time, you have to include the date (which then renders these relative "ago" strings useless). So you might just get rid of this "ago" portion:
- (NSString *)relativeDateStringForDate:(NSDate *)date {
// get the number of days differences
NSCalendarUnit units = NSCalendarUnitDay | NSCalendarUnitWeekOfMonth | NSCalendarUnitMonth | NSCalendarUnitYear;
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *dateComponents = [calendar components:units fromDate:date];
NSDateComponents *nowComponents2 = [calendar components:units fromDate:[NSDate date]];
NSDateComponents *components = [calendar components: NSCalendarUnitDay fromDateComponents:dateComponents toDateComponents:nowComponents2 options:0];
if (components.day > 1) {
// build date/time string
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
formatter.timeStyle = NSDateFormatterShortStyle;
formatter.dateStyle = NSDateFormatterShortStyle;
return [formatter stringFromDate:date];
} else {
// build time string
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
formatter.timeStyle = NSDateFormatterShortStyle;
NSString *timeString = [formatter stringFromDate:date];
if (components.day == 1) {
return [NSString stringWithFormat:#"%#, %#", NSLocalizedString(#"Yesterday", #"day before today"), timeString];
} else {
return [NSString stringWithFormat:#"%#, %#", NSLocalizedString(#"Today", #"well, er, today"), timeString];
}
}
}
That solves the weird "3 months ago, 11:20am" problem, but then again, it's no longer a relative date/time string.
Another option is to abandon absolute time altogether, and just show a relative string:
- (NSString *)relativeDateStringForDate:(NSDate *)date {
NSCalendarUnit units = NSCalendarUnitSecond | NSCalendarUnitMinute | NSCalendarUnitHour | NSCalendarUnitDay | NSCalendarUnitWeekOfMonth | NSCalendarUnitMonth | NSCalendarUnitYear;
NSDateComponentsFormatter *formatter = [[NSDateComponentsFormatter alloc] init];
formatter.allowedUnits = units;
formatter.maximumUnitCount = 2;
formatter.unitsStyle = NSDateComponentsFormatterUnitsStyleFull;
return [NSString stringWithFormat:#"%# %#", [formatter stringFromDate:date toDate:[NSDate date]], NSLocalizedString(#"ago", #"x days _ago_")];
}
The details of the above samples is less important than the basic concepts, namely:
Be careful using date components when determining "today" vs "yesterday";
Use date formatters when trying to create the time strings or date/time strings; and
Use date components formatters when trying to build a string that represents the amount of time (or days) that has elapsed.

compare date from textfield

I have implemented two textFields From and To in ViewController.When the user selects the textField he is able to select the date from the calendar. The selected Date is stored in the TextField as
YYYY-MM-dd format.
And I have implemented a calculate button in ViewController.When the Two TextField are filled i need to do some work.
When the two textField are filled and the From TextField is greater , I want to display an alert when the From TextField date is Greater than To TextField.
How can i Compare it...?
Perfect solution
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"yyyy-MM-dd"];
NSString *textFieldDateString1 = #"2016-07-14";
NSString *textFieldDateString2 = #"2016-07-15";
NSDate *date1 = [dateFormatter dateFromString:textFieldDateString1];
NSDate *date2 = [dateFormatter dateFromString:textFieldDateString2];
if ([date1 compare:date2] == NSOrderedDescending) {
NSLog(#"date1 is later than date2");
} else if ([date1 compare:date2] == NSOrderedAscending) {
NSLog(#"date1 is earlier than date2");
} else {
NSLog(#"dates are the same");
}
Printed Result is
date1 is earlier than date2
Date Comparision
Compare Two dates
NSDateFormatter * df = [[NSDateFormatter alloc] init];
[df setDateFormat: #"yyyy-MM-dd"];
NSDate * dt1 ;
NSDate * dt2 ;
dt1 = [df dateFromString: txt1.text];
dt2 = [df dateFromString: txt2.text];
NSComparisonResult result = [dt1 compare: dt2];
switch (result) {
case NSOrderedAscending:
NSLog(#"%# is greater than %#", dt2, dt1);
break;
case NSOrderedDescending:
NSLog(#"%# is less %#", dt2, dt1);
break;
case NSOrderedSame:
NSLog(#"%# is equal to %#", dt2, dt1);
break;
default:
NSLog(#"erorr dates %#, %#", dt2, dt1);
break;
}
Hope this will help you....
i think you are looking for this functionality..
NSCalendar* currentCalendar = [NSCalendar currentCalendar];
NSCalendarUnit unitFlags = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute;
NSDateComponents *differenceComponents = [currentCalendar components:unitFlags fromDate:postdate toDate:[NSDate date] options:0];
NSInteger yearDifference = [differenceComponents year];
NSInteger monthDifference = [differenceComponents month];
NSInteger dayDifference = [differenceComponents day];
NSInteger hourDifference = [differenceComponents hour];
NSInteger minuteDifference = [differenceComponents minute];
i hope this will help you..
First you have to convert this two text field string date into NSDate object and and use compare: method of date to compare date.
NSString *dateString1 = #"2016-05-31"; //First text field value
NSString *dateString2 = #"2016-05-31"; //Second text field value
NSDateFormatter *dateFormatter=[NSDateFormatter new];
[dateFormatter setDateFormat:#"YYYY-MM-dd"];
NSDate *date1=[dateFormatter dateFromString:dateString1];
NSDate *date2=[dateFormatter dateFromString:dateString2];
if ([date1 compare:date2] == NSOrderedDescending) {
NSLog(#"date1 is later than date2");
} else if ([date1 compare:date2] == NSOrderedAscending) {
NSLog(#"date1 is earlier than date2");
} else {
NSLog(#"dates are the same");
}

loading upcoming events by comparing their dates with the calendar date

I have found the below code online for comparing two dates (the date of the calendar and some another date) what I would like help with is modifying this code so that it compares the calendar date with the date of an event where date here is key for each event within NSArray (json file) .. Also how I could use this later with NSPredicate so that I can load only the events with components (difference between two dates in days) at least more than 1 day since Im going to have UIButton called future events when the user click on it, all the future events should be loaded .. I would really appreciate any help and code examples since Im very new to objective C and Xcode. Thanks.
#implementation HomeViewController {
NSArray *_events;
}
- (BOOL)isSameDay:(NSDate*)date
{
NSCalendar* calendar = [NSCalendar currentCalendar];
NSDate *currDate = [NSDate date];
//date = [_events objectAtIndex:date];
unsigned unitFlags = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit;
NSDateComponents* comp1 = [calendar components:unitFlags fromDate:date];
NSDateComponents* comp2 = [calendar components:unitFlags fromDate:currDate];
NSDateComponents *components = [calendar components:unitFlags
fromDate:currDate
toDate:date
options:0];
NSLog(#"Days between dates: %#", components);
return [comp1 day] == [comp2 day] &&
[comp1 month] == [comp2 month] &&
[comp1 year] == [comp2 year];
}
To get the number of days remaining for a date from now, you can use the method below:
-(long)daysRemaining:(NSDate*) date
{
NSDate *now = [NSDate date];
NSTimeInterval dateDiff = [date timeIntervalSinceNow] - [now timeIntervalSinceNow];
CGFloat numberOfDaysRemaining = (dateDiff/(60*60*24));
return ceil(numberOfDaysRemaining);
}
So you can call to get the number of days remaining like this:
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"yyyy-MM-dd"];
NSDate *dateToCompare = [dateFormatter dateFromString: #"2014-02-08"];
long numberDays = [self daysRemaining:dateToCompare];
For this case, the result is 2 days remaining. Note that a negative result indicates that was passed n days.
To filter the array (2 days remaining events) making a copy of it:
NSArray* dates = [[NSArray alloc] initWithObjects:
[dateFormatter dateFromString: #"2014-02-08"],
[dateFormatter dateFromString: #"2014-02-05"],
[dateFormatter dateFromString: #"2014-02-10"],
[dateFormatter dateFromString: #"2014-02-08"], nil];
NSArray *filteredArray = [dates filteredArrayUsingPredicate:
[NSPredicate predicateWithBlock:
^BOOL(id evaluatedObject, NSDictionary *bindings) {
long daysRemaining = [self daysRemaining:(NSDate*)evaluatedObject];
return daysRemaining == 2; // if someMethod returns YES, the object is kept
}
]];
To filter an NSMutableArray in place:
[mutableArray filterUsingPredicate:[NSPredicate predicateWithBlock:
^BOOL(id evaluatedObject, NSDictionary *bindings) {
long daysRemaining = [self daysRemaining:(NSDate*)evaluatedObject];
return daysRemaining == 2; // if someMethod returns YES, the object is kept
}
]];
[displayedEvents addObjectsFromArray:[_events filteredArrayUsingPredicate:
[NSPredicate predicateWithBlock:
^BOOL(Events * event, NSDictionary *bindings) {
[dateFormatter dateFromString: event.date];
long daysRemaining = [self daysRemaining: (NSDate*)event.date];
return daysRemaining > 1; // if someMethod returns YES, the object is kept
}
]]];

If statement with dates

what I am trying to do is make a if statement with dates using greater than less than signs. For some reason only the greater than sign works. Here is my code:
NSDate *currDate = [NSDate date];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init];
[dateFormatter setDateFormat:#"HHmm"];
NSString *dateString = [dateFormatter stringFromDate:currDate];
NSLog(#"%#",dateString);
if (dateString < #"0810" && dateString > #"0800") {
NSLog(#"Homeroom");
}
else {
NSLog(#"no");
}
The output for this code would be if the time was 8:03:
2013-04-08 08:03:47.956 Schedule2.0[13200:c07] 0803
2013-04-08 08:03:47.957 Schedule2.0[13200:c07] no
If I were to make is so where it is only the greater then sign like this:
if (dateString > #"0800") {
NSLog(#"Homeroom");
}
else {
NSLog(#"no");
}
The output would be this:
2013-04-08 08:03:29.748 Schedule2.0[14994:c07] 0803
2013-04-08 08:03:29.749 Schedule2.0[14994:c07] Homeroom
create a NSDate object with the time 8:10 and one with 8:00. Now you can compare the given date with both these dates
if(([date0800 compare:date] == NSOrderingAscending) && [date0810 compare:date] == NSOrderingDescending) )
{
// date is between the other
}
to create the boundaries dates you can do this
NSDate *date = [NSDate date]; // now
NSDateComponents *components = [[NSCalendar currentCalendar] components:( NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit ) fromDate:date];
components.hour = 8;
components.minute = 0;
NSDate *date0800 = [[NSCalendar currentCalendar] dateFromComponents: components];
components.minute = 10;
NSDate *date0810 = [[NSCalendar currentCalendar] dateFromComponents: components];
if you insist of using operators like < and >, you can use the timeinterval of the date objects.
if(([date0800 timeIntervalSince1970] < [date timeIntervalSince1970]) && ([date0810 timeIntervalSince1970] > [date timeIntervalSince1970]))
{
// date lays between the other two
}
but beware of checking == on it, as it could be faulty due to rounding errors.
Here you are comparing string objects, with < and >, which does not do what you are expecting. You can use NSDateComponents to get the hour and minute to compare those:
NSDate *today = [NSDate date];
NSCalendar *gregorian = [[NSCalendar alloc]
initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *components =
[gregorian components:(NSHourCalendarUnit | NSMinuteCalendarUnit ) fromDate:today];
NSInteger hour = [weekdayComponents hour];
NSInteger minutes = [weekdayComponents minute];
BOOL homeroom = (hour == 8) && (minute < 10);
Or you can create a specific NSDate for 8:10 and 8:00 using NSDateFormater and using the compare: function.
NSString objects are objects, and when you compare objects with C comparison operators (==, >, <, etc.) you are comparing their addresses, not their values. You need to use compare, such as:
if ([dateString compare:#"0810"] == NSOrderedAscending &&
[dateString compare:#"0800"] == NSOrderedDescending) { ...
Though I'd recommend converting to NSDate objects in most cases if you want to compare dates and times.
You can't use > or < to compare string objects. That actually compares pointers so we won't get into why > 'works' and < 'doesn't'.
For this kind of date comparison use NSDateComponents
NSDateComponents Reference
Here's the gist of a category I wrote on NSDate. I found it made my code more readable.
https://gist.github.com/nall/5341477
#interface NSDate(SZRelationalOperators)
-(BOOL)isLessThan:(NSDate*)theDate;
-(BOOL)isLessThanOrEqualTo:(NSDate*)theDate;
-(BOOL)isGreaterThan:(NSDate*)theDate;
-(BOOL)isGreaterThanOrEqualTo:(NSDate*)theDate;
#end

Resources