97

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?

Vincent Guerci
  • 14,379
  • 4
  • 50
  • 56
cyclingIsBetter
  • 17,447
  • 50
  • 156
  • 241
  • 1
    I don't completely understand your question, what are you trying to achieve? – arclight May 24 '11 at 14:32
  • date one and date two can be one = 15/05/2011 and two = 31/05/2011 but they must be also the same day one = 24/05/2011 and two = 24/05/2011 then I must check if myData is beetween date one and date two – cyclingIsBetter May 24 '11 at 14:34
  • Just extract the year, month, and date and compare them in that order. If there is a tie then compare the next field. – Himadri Choudhury May 24 '11 at 16:44
  • 2
    possible duplicate of [comparing dates in iPhone programming](http://stackoverflow.com/questions/994855/comparing-dates-in-iphone-programming) or [Compare two dates](http://stackoverflow.com/questions/5727821/compare-two-dates) or [Compare two NSDate fails](http://stackoverflow.com/questions/5204960/compare-two-nsdate-fails) or [many others](http://stackoverflow.com/search?q=compare+nsdate) – jscs May 24 '11 at 18:28

6 Answers6

210

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.

Vincent Guerci
  • 14,379
  • 4
  • 50
  • 56
  • but f ([date1 compare:date2]==NSOrderedSame) check also the hour minute and seconds and I don't want it – cyclingIsBetter May 24 '11 at 15:12
  • 1
    you question was a bit unclear sorry, give a look at http://stackoverflow.com/questions/1889164/3092009#3092009, you'll find the answer to this. – Vincent Guerci May 24 '11 at 18:37
  • This answer is correct in both ways. To control the date components you are comparing use `NSDateComponents` – Nazir Nov 21 '16 at 10:11
33

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];
Cœur
  • 37,241
  • 25
  • 195
  • 267
ytpm
  • 4,962
  • 6
  • 56
  • 113
23

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

lukas
  • 2,300
  • 6
  • 28
  • 41
Himadri Choudhury
  • 10,217
  • 6
  • 39
  • 47
16

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];
}
Matthias Bauch
  • 89,811
  • 20
  • 225
  • 247
2

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 :)

Akhtar
  • 3,172
  • 5
  • 19
  • 21
2

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
} 
JeremyP
  • 84,577
  • 15
  • 123
  • 161