pnizzle
pnizzle

Reputation: 6431

NSArray filter using NSPredicate, comparing dates

I have a Person entity where the attribute date_of_birth is declared as NSString. If I have an array of 'Person' instances and I need to filter them down to only those whose date_of_birth is less that 25/11/2005 I am using a predicate whose format when NSLogged is:

FUNCTION(date_of_birth, "yyyy_MM_dd_dateFormat") <[cd] CAST(154575908.000000, "NSDate")

where yyyy_MM_dd_dateFormat() is a category method on NSString that returns the string instance as a date.

I am not getting the expected results. Am I doing something wrong, and what is the bit where it says CAST(154575908.000000, "NSDate" and is that valid?

UPDATE: changing the date_of_birth attribute type to NSDate is not an option at the moment due to the size, maturity and complexity of the project.

Upvotes: 2

Views: 1688

Answers (2)

Anoop
Anoop

Reputation: 419

Here, person date is type of NSDate.

NSPredicate *predicate2 = [NSPredicate predicateWithFormat:@"date >= %@",person.date];

list=[list filteredArrayUsingPredicate:predicate2];

But in case you saved with NSString type , than you need to cast comparison date into string than use like instead of >=

Upvotes: 0

danh
danh

Reputation: 62676

Dates are best represented by NSDate, which implements inequality via earlierDate: and laterDate: methods. These answer the earlier/later date between the receiver and the parameter.

Your conversion method probably looks something like this ...

// return an NSDate for a string given in dd/MM/yyyy
- (NSDate *)dateFromString:(NSString *)string {
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    [formatter setDateFormat:@"dd/MM/yyyy"];
    return [formatter dateFromString:string];
}

The array can be filtered with a block-based NSPredicate that uses NSDate comparison...

NSDate *november25 = [self dateFromString:@"25/11/2005"];
NSPredicate *predicate = [NSPredicate predicateWithBlock:^BOOL(Person *person, NSDictionary *bind){
    // this is the important part, lets get things in NSDate form so we can use them.
    // of course it would be quicker to alter the data type, but we can covert on the fly
    NSDate *dob = [self dateFromString:person.date_of_birth];
    return date_of_birth == [november25 earlierDate:dob];
}];

// assumes allPeople is an NSArray of Person objects to be filtered
// and assumes Person has an NSString date_of_birth property
NSArray *oldPeople = [allPeople filteredArrayUsingPredicate:predicate];

Upvotes: 2

Related Questions