SPUDERMAN
SPUDERMAN

Reputation: 187

Comparing if two NSDate objects are the same

Below is my comparison code:

 int countTrue = 0;
 //NSDate *datee = [[self.reminderResultsArray objectAtIndex:0] date];

for(int i = 0; i < self.reminderResultsArray.count; i++){
    if([[NSCalendar currentCalendar] isDate:self.actualSelectedDate inSameDayAsDate:[[self.reminderResultsArray objectAtIndex:i] date]]){
        countTrue++;
        NSLog(@"Count true: %d", countTrue);
    } 
}

Below is the data in my self.reminderResults.array:

(lldb) po [[self.reminderResultsArray objectAtIndex:1] date] 2017-06-02 09:38:35 +0000

(lldb) po [[self.reminderResultsArray objectAtIndex:0] date] 2017-05-27 09:37:48 +0000

(lldb) po [[self.reminderResultsArray objectAtIndex:1] date] 2017-06-02 09:38:35 +0000

(lldb) po [[self.reminderResultsArray objectAtIndex:2] date] 2017-06-02 10:09:48 +0000

(lldb) po [[self.reminderResultsArray objectAtIndex:3] date] 2017-06-02 10:12:30 +0000

(lldb) po [[self.reminderResultsArray objectAtIndex:4] date] 2017-06-03 08:49:33 +0000

My self.actualSelectedDate value is:

po self.actualSelectedDate
2017-06-02 16:00:00 +0000

By right, the countTrue value should be 3 but instead it is only returning value of 1. Any problem with my code?

Upvotes: 0

Views: 60

Answers (4)

Ken Thomases
Ken Thomases

Reputation: 90571

The dates, when logged, are describing themselves relative to UTC (i.e. time zone +0000). This may be misleading you.

The calendar object you're getting from [NSCalendar currentCalendar] will use your system's current time zone. Unless your time zone is UTC, that means that the day of month shown in the output is not the day of month that's relevant for the -isDate:inSameDayAsDate: comparison. (In the general case, more components than just the day of month could differ in the string representation of a date depending on time zone.)

To figure out why the comparison is not working how you think it should, you first need to figure out what the year, month, and day of month are for all of those dates in your time zone. Then it will be clear. I expect the -isDate:inSameDayAsDate: method is working exactly as it's supposed to and you were just misunderstanding the actual day (in your time zone) of the dates you were working with.

Alternatively, if you're really interested in what the day is in UTC, then you need to use a calendar object whose timeZone has been set to [NSTimeZone timeZoneWithName:@"UTC"].

Upvotes: 1

Maddy
Maddy

Reputation: 1668

Try this,

    int countTrue = 0 ; 

    NSString  *actualSelectedDateAsString = @"2017-06-02 16:00:00 +0000";

    NSArray   *reminderResultsArray = @[@"2017-06-02 09:38:35 +0000",
                                      @"2017-05-27 09:37:48 +0000",
                                      @"2017-06-02 09:38:35 +0000",
                                      @"2017-06-02 10:09:48 +0000",
                                      @ "2017-06-02 10:12:30 +0000",
                                      @"2017-06-03 08:49:33 +0000"];

//  use date formatter to convert string to date and set the date format as per your requirement.

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

    NSDate *actualSelectedDate = [dateFormatter dateFromString:actualSelectedDateAsString]; // convert string to date.


    for (int i=0 ; i<reminderResultsArray.count ; i++){

        if( [[NSCalendar currentCalendar]isDate:actualSelectedDate inSameDayAsDate:[dateFormatter dateFromString:[reminderResultsArray objectAtIndex:i]]]){

            countTrue++;

            NSLog(@"Count true: %d", countTrue);
        }

    }

    NSLog(@"Count true: %d", countTrue); // result would be 4

Upvotes: 0

Anuj Panwar
Anuj Panwar

Reputation: 683

If you observe the logs then time is different and because of that NSCalender method will consider them as a different date.

If you want to do only date comparison then first create date object using date formatter dd/mm/yyyy then compare the date.

or instead you can check the day month and year components

+ (BOOL)isSameDayWithDate1:(NSDate*)date1 date2:(NSDate*)date2 {
    NSCalendar* calendar = [NSCalendar currentCalendar];

    unsigned unitFlags = NSCalendarUnitYear | NSCalendarUnitMonth |      NSCalendarUnitDay;
    NSDateComponents* comp1 = [calendar components:unitFlags fromDate:date1];
    NSDateComponents* comp2 = [calendar components:unitFlags fromDate:date2];

    return [comp1 day]   == [comp2 day] &&
    [comp1 month] == [comp2 month] &&
    [comp1 year]  == [comp2 year];
}

Upvotes: 1

Andr&#233; Slotta
Andr&#233; Slotta

Reputation: 14030

if you only care about the date part of the NSDate object you could do it like this:

let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss Z"

let actualSelectedDateString = "2017-06-02 16:00:00 +0000"
let actualSelectedDate = dateFormatter.dateFromString(actualSelectedDateString)!

let dateStrings = ["2017-06-02 09:38:35 +0000",
                   "2017-05-27 09:37:48 +0000",
                   "2017-06-02 09:38:35 +0000",
                   "2017-06-02 10:09:48 +0000",
                   "2017-06-02 10:12:30 +0000",
                   "2017-06-03 08:49:33 +0000"]

let dates = dateStrings.map({dateFormatter.dateFromString($0)!})

let calendar = NSCalendar.currentCalendar()
let count = dates.filter({calendar.isDate($0, inSameDayAsDate: actualSelectedDate)}).count

Upvotes: 0

Related Questions