How to test if today is not after a specific date? - objective-c

In Objective-C, how to test if today is not after a specific date?
I am using the following way but am curious if there is a better way or other alternatives to go about this.
NSString *dateString = #"20140928";
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"yyyyMMdd"];
NSDate *expirationDate = [dateFormat dateFromString:dateString];
NSDate *today = [NSDate date];
if ([today laterDate:expirationDate] != today) {
NSLog(#"Today is not after expirationDate");
}

Most of your code is getting the expiration date so that doesn't really count.
Once you have the date then using laterDate: or compare: with [NSDate date] are two simple ways.
You could also do:
if ([expirationDate timeIntervalSinceNow] > 0) {
// expiration date is after "now"
}
This avoids the need to use [NSDate date].

As an alternative there is:
if ([today compare:expirationDate] == NSOrderedAscending)
// expirationDate comes "after" today
if ([today compare:expirationDate] == NSOrderedDescending)
// expirationDate comes "before" today
if ([today compare:expirationDate] == NSOrderedSame)
// expirationDate equals today

Related

Calculate days between two days errror objective c

hello i am trying to calculate days between today and past date 10-05-2015 in objective c. but when i put condition as follows it always going in if condition. what should be the problem in my code?
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
// this is imporant - we set our input date format to match our input string
// if format doesn't match you'll get nil from your string, so be careful
[dateFormatter setDateFormat:#"dd-MM-yy hh:mm a"];
NSDate *Startdate = [[NSDate alloc] init];
Startdate = [dateFormatter dateFromString:eventstartdate];
NSDateFormatter *dateFormatter1 = [[NSDateFormatter alloc] init];
// this is imporant - we set our input date format to match our input string
// if format doesn't match you'll get nil from your string, so be careful
[dateFormatter1 setDateFormat:#"MM-dd-yy hh:mm a"];
NSDate *CurrentDate = [[NSDate alloc] init];
CurrentDate = [dateFormatter1 dateFromString:Currentdate];
NSDate *startDate= Startdate;
NSDate *endDate = CurrentDate ;
if ([CurrentDate earlierDate:Startdate])
{
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *differenceComponents = [calendar components:NSCalendarUnitDay fromDate:startDate toDate:endDate options:0];
NSInteger numDays = differenceComponents.day;
}
else
{
UIAlertView *AlertMsg =[[UIAlertView alloc] initWithTitle:nil message:[NSString stringWithFormat:#"Event is scheduled at %#",eventstartdate] delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[AlertMsg show];
}
get same type of date format as 2015-05-21 12:00 for startdate and end date besides the i have given different formats.
is there any problem with my code?
From Docs of Apple : NSDate compare:
Returns an NSComparisonResult value that indicates the temporal ordering of the receiver and another given date.
- (NSComparisonResult)compare:(NSDate *)anotherDate
Parameters anotherDate
The date with which to compare the
receiver. This value must not be nil.
If the value is nil, the behavior is
undefined and may change in future
versions of Mac OS X.
Return Value
If:
The receiver and anotherDate are
exactly equal to each other,
NSOrderedSame
The receiver is later in
time than anotherDate,
NSOrderedDescending
The receiver is
earlier in time than anotherDate,
NSOrderedAscending
In other words:
If you want to check for same date
if ([date1 compare:date2] == NSOrderedSame)
{
NSLog(#"dates are the same");
}
If you want to check for later date
if ([date1 compare:date2] == NSOrderedDescending)
{
NSLog(#"date1 is later than date2");
}
If you want to check for earlier date
if ([date1 compare:date2] == NSOrderedAscending)
{
NSLog(#"date1 is earlier than date2");
}

Comparing two dates in Objective-C [duplicate]

This question already has answers here:
How to compare two NSDates: Which is more recent?
(13 answers)
Closed 9 years ago.
I need to compare the current date/time against user selected date/time.
Below is my code snippet
-(IBAction)btnSaveTouched:(id)sender {
NSDate *today = [NSDate date];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"yyyy-MM-dd H:mm"];
NSString *formatterDate = [formatter stringFromDate: today];
NSComparisonResult comparisionResult1 = [self.paramSchedule1StartSQLDateString compare:formatterDate];
if (comparisionResult1 == NSOrderedAscending) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error" message:#"Viewing schedule must be after current time." delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
return;
}
NSLog(#"comparisionResult1 %d", comparisionResult1);
}
After btnSaveTouched(UIButton) is tap, the date/time will be store into the database and return back to the screen. (view controller where user select the date/time)
However, when I tried to compare another date/time, the alert will be show even though I selected date/time later then the current date/time.
After NSLog the comparsionResult1, the value is 1 for the second time checking always.
I tried to do this NSComparsionResult comparisionResult1 = 0; but it's not working properly. Is there any ways to go about doing this?
Please advise.
Thanks
Comparison between dates you need to be careful, expecially If you compare with NSString, you must make sure both dates are arranged, and you need to be careful with both formats..So i recomend you compare two NSDate.
Sample:
NSDate *date1 = //…
NSDate *date2 = //…
switch ([date1 compare:date2]) {
case NSOrderedAscending:
//Do your logic when date1 > date2
break;
case NSOrderedDescending:
//Do your logic when date1 < date2
break;
case NSOrderedSame:
//Do your logic when date1 = date2
break;
}
Of course, you can implement a category for NSDate. But already exists, and i like to use this one: NSDate Category, witch you can edit and customize as you wish.
Try this code for any comparison between dates... You should not compare date in the form of string. Compare the dates before conversion to string. Convert the self.paramSchedule1StartSQLDateString into date format using dateFromString function of the formatter by specifying the exact date format as that of the dateString. Then compare the dates using following function.
NSDate *today = [NSDate date]; // current date
NSDate *newDate = self.paramSchedule1StartSQLDateString; // other date
NSComparisonResult result;
result = [today compare:newDate]; // comparing two dates
if(result == NSOrderedAscending)
NSLog(#"today is less");
else if(result == NSOrderedDescending)
NSLog(#"newDate is less");
else if(result == NSOrderedSame)
NSLog(#"Both dates are same");
else
NSLog(#"Date cannot be compared");
NSDateFormatter *dateFormatter = [[[NSDateFormatter alloc] init] autorelease];
[dateFormatter setDateFormat:#"yyyy-MM-dd"];
NSDate *date1 = [dateFormatter dateFromString:TodayDate];
NSDateFormatter *dateFormatte = [[[NSDateFormatter alloc] init] autorelease];
[dateFormatte setDateFormat:#"yyyy-MM-dd"];
NSDate *date2 = [dateFormatte dateFromString:CompareDate];
unsigned int unitFlags = NSDayCalendarUnit;
NSCalendar *gregorian = [[NSCalendar alloc]initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *comps = [gregorian components:unitFlags fromDate:date1 toDate:date2 options:0];
int days = [comps day];
NSLog(#"%d",days);

Check If Date Is Between Two Dates

Good afternoon,
How do you check if a date is between two dates? I know I have to convert the data strings to NSDate values first:
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"MM/dd/yyyy"];
NSDate *date1 = [dateFormatter dateFromString:#"01/01/2001"];
NSDate *date2 = [dateFormatter dateFromString:#"01/01/2010"];
NSDate *userDate = [dateFormatter dateFromString:#"12/12/2001"];
And then I have to use an if-statement, but I am not quite sure how to go about it. Here is what I need:
if (userDate is between date1 and date2)
{
}
Any help with the if-statement would be appreciated. Thank you!
Use NSDate -compare::
if (([date1 compare:userDate] == NSOrderedAscending) && ([date2 compare:userDate] == NSOrderedDescending)) {
// Do something
}
of the top of my head so check the syntax ;-)
if (([userDate laterDate: date1] == userDate) && ([userDate laterDate: date2] == date2)){
}
if(([userDate compare: date1] == NSOrderedDescending) && ([userDate compare: date2] == NSOrderedAscending)){
//do something
}

Reliably checking whether NSDate falls within given hour, day or week

I need to take a stored NSDate and reliably determine whether it falls within the current moment's hour, day or week. I seem to have hacked together a solution, but not having solved this problem before, am not entirely confident that it's a reliable one.
Will this survive user-set 12 vs 24 hour time? the date formatting guide indicates that this user setting can lead to some unanticipated date behavior: "In iOS, the user can override the default AM/PM versus 24-hour time setting. This may cause NSDateFormatter to rewrite the format string you set."
What about the basic code pattern for this problem? Does this code seem to reliably serve its purpose? I hate to post a "check my code" sort of question, but it's an unfamiliar-enough problem to me, and tricky enough to rigorously test, that it seemed justified. NSDateFormatter is also relatively new to me; another motivation for the question.
NOTE: The main source of my nervousness is that converting dates to strings and then doing a string compare seems an inherently fragile method of solving this problem. But it's the best I could come up with.
Quick reference: the dateFormats I used for each of the three cases were:
dateFormat = #"yyyyMMddHH"; // For "this hour" check
dateFormat = #"yyyyMMdd"; // For "today" check
dateFormat = #"yyyyww"; // For "this week" check
Thanks! Code Follows:
- (BOOL)didThisCycle {
// Case 1: hourly; Case 2: daily; Case 3: weekly
BOOL did = NO;
NSDate *now = [NSDate date];
NSDate *lastDid = [self.didDates lastObject];
if (![lastDid isKindOfClass:[NSDate class]]) { // Crash protection
return NO;
}
int type = [self.goalType intValue];
switch (type) {
case 1:
{
// If hourly check hour
NSDateFormatter *formatter = [[[NSDateFormatter alloc] init] autorelease];
formatter.dateFormat = #"yyyyMMddHH";
NSString *nowString = [formatter stringFromDate:now];
NSString *lastDidString = [formatter stringFromDate:lastDid];
if ([nowString isEqualToString:lastDidString]) {
did = YES;
} else {
did = NO;
}
break;
}
case 2:
{
// If daily check day
NSDateFormatter *formatter = [[[NSDateFormatter alloc] init] autorelease];
formatter.dateFormat = #"yyyyMMdd";
NSString *nowString = [formatter stringFromDate:now];
NSString *lastDidString = [formatter stringFromDate:lastDid];
if ([nowString isEqualToString:lastDidString]) {
did = YES;
} else {
did = NO;
}
break;
}
case 3:
{
// If weekly check week
NSDateFormatter *formatter = [[[NSDateFormatter alloc] init] autorelease];
formatter.dateFormat = #"yyyyww";
NSString *nowString = [formatter stringFromDate:now];
NSString *lastDidString = [formatter stringFromDate:lastDid];
if ([nowString isEqualToString:lastDidString]) {
did = YES;
} else {
did = NO;
}
break;
}
default:
{
did = NO;
break;
}
}
return did;
}
Use the NSDateComponents class, like so:
NSDate *someDate = // whatever
NSDate *now = [NSDate date];
NSDateComponents *thenComponents = [[NSCalendar currentCalendar] components:NSHourCalendarUnit|NSDayCalendarUnit|NSMonthCalendarUnit|NSYearCalendarUnit fromDate:someDate];
NSDateComponents *nowComponents = [[NSCalendar currentCalendar] components:NSHourCalendarUnit|NSDayCalendarUnit|NSMonthCalendarUnit|NSYearCalendarUnit fromDate:now];
if([thenComponents year] == [nowComponents year] && [thenComponents month] == [nowComponents month] && [thenComponents day] == [nowComponents day] && [thenComponents hour] == [nowComponents hour])
{
// hooray
}
Remove the “hour” component if you just want to check the day, or remove both that and “day” (and replace with NSWeekCalendarUnit and the -week method) to check the week.

iOS: Compare two dates

I have a NSDate that I must compare with other two NSDate and I try with NSOrderAscending and NSOrderDescending but if my date is equal at other two dates?
Example: if I have a myDate = 24/05/2011 and other two that are one = 24/05/2011 and two 24/05/2011 what can I use?
According to Apple documentation of NSDate compare:
Returns an NSComparisonResult value that indicates the temporal ordering of the receiver and another given date.
- (NSComparisonResult)compare:(NSDate *)anotherDate
Parameters anotherDate
The date with which to compare the
receiver. This value must not be nil.
If the value is nil, the behavior is
undefined and may change in future
versions of Mac OS X.
Return Value
If:
The receiver and anotherDate are
exactly equal to each other,
NSOrderedSame
The receiver is later in
time than anotherDate,
NSOrderedDescending
The receiver is
earlier in time than anotherDate,
NSOrderedAscending
In other words:
if ([date1 compare:date2] == NSOrderedSame) ...
Note that it might be easier in your particular case to read and write this :
if ([date2 isEqualToDate:date2]) ...
See Apple Documentation about this one.
After searching, I've got to conclusion that the best way of doing it is like this:
- (BOOL)isEndDateIsSmallerThanCurrent:(NSDate *)checkEndDate
{
NSDate* enddate = checkEndDate;
NSDate* currentdate = [NSDate date];
NSTimeInterval distanceBetweenDates = [enddate timeIntervalSinceDate:currentdate];
double secondsInMinute = 60;
NSInteger secondsBetweenDates = distanceBetweenDates / secondsInMinute;
if (secondsBetweenDates == 0)
return YES;
else if (secondsBetweenDates < 0)
return YES;
else
return NO;
}
You can change it to difference between hours also.
If you want to compare date with format of dd/MM/yyyy only, you need to add below lines between NSDate* currentdate = [NSDate date]; && NSTimeInterval distance
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"dd/MM/yyyy"];
[dateFormatter setLocale:[[[NSLocale alloc] initWithLocaleIdentifier:#"en_US"]
autorelease]];
NSString *stringDate = [dateFormatter stringFromDate:[NSDate date]];
currentdate = [dateFormatter dateFromString:stringDate];
I take it you are asking what the return value is in the comparison function.
If the dates are equal then returning NSOrderedSame
If ascending ( 2nd arg > 1st arg ) return NSOrderedAscending
If descending ( 2nd arg < 1st arg ) return NSOrderedDescending
I don't know exactly if you have asked this but if you only want to compare the date component of a NSDate you have to use NSCalendar and NSDateComponents to remove the time component.
Something like this should work as a category for NSDate:
- (NSComparisonResult)compareDateOnly:(NSDate *)otherDate {
NSUInteger dateFlags = NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit;
NSCalendar *gregorianCalendar = [[[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar] autorelease];
NSDateComponents *selfComponents = [gregorianCalendar components:dateFlags fromDate:self];
NSDate *selfDateOnly = [gregorianCalendar dateFromComponents:selfComponents];
NSDateComponents *otherCompents = [gregorianCalendar components:dateFlags fromDate:otherDate];
NSDate *otherDateOnly = [gregorianCalendar dateFromComponents:otherCompents];
return [selfDateOnly compare:otherDateOnly];
}
NSDate actually represents a time interval in seconds since a reference date (1st Jan 2000 UTC I think). Internally, a double precision floating point number is used so two arbitrary dates are highly unlikely to compare equal even if they are on the same day. If you want to see if a particular date falls on a particular day, you probably need to use NSDateComponents. e.g.
NSDateComponents* dateComponents = [[NSDateComponents alloc] init];
[dateComponents setYear: 2011];
[dateComponents setMonth: 5];
[dateComponents setDay: 24];
/*
* Construct two dates that bracket the day you are checking.
* Use the user's current calendar. I think this takes care of things like daylight saving time.
*/
NSCalendar* calendar = [NSCalendar currentCalendar];
NSDate* startOfDate = [calendar dateFromComponents: dateComponents];
NSDateComponents* oneDay = [[NSDateComponents alloc] init];
[oneDay setDay: 1];
NSDate* endOfDate = [calendar dateByAddingComponents: oneDay toDate: startOfDate options: 0];
/*
* Compare the date with the start of the day and the end of the day.
*/
NSComparisonResult startCompare = [startOfDate compare: myDate];
NSComparisonResult endCompare = [endOfDate compare: myDate];
if (startCompare != NSOrderedDescending && endCompare == NSOrderedDescending)
{
// we are on the right date
}
Check the following Function for date comparison first of all create two NSDate objects and pass to the function:
Add the bellow lines of code in viewDidload or according to your scenario.
-(void)testDateComaparFunc{
NSString *getTokon_Time1 = #"2016-05-31 03:19:05 +0000";
NSString *getTokon_Time2 = #"2016-05-31 03:18:05 +0000";
NSDateFormatter *dateFormatter=[NSDateFormatter new];
[dateFormatter setDateFormat:#"yyyy-MM-dd hh:mm:ss Z"];
NSDate *tokonExpireDate1=[dateFormatter dateFromString:getTokon_Time1];
NSDate *tokonExpireDate2=[dateFormatter dateFromString:getTokon_Time2];
BOOL isTokonValid = [self dateComparision:tokonExpireDate1 andDate2:tokonExpireDate2];}
here is the function
-(BOOL)dateComparision:(NSDate*)date1 andDate2:(NSDate*)date2{
BOOL isTokonValid;
if ([date1 compare:date2] == NSOrderedDescending) {
//"date1 is later than date2
isTokonValid = YES;
} else if ([date1 compare:date2] == NSOrderedAscending) {
//date1 is earlier than date2
isTokonValid = NO;
} else {
//dates are the same
isTokonValid = NO;
}
return isTokonValid;}
Simply change the date and test above function :)