问题
I've some data (as NSDictionary
in an NSMutableArray
), a sample data is like,

Consider each row as NSDictionary
and entire table is an NSMutableArray
contains events.
I want to result between two dates, so I'm using NSPredicate
to filter my data.
Here's my code snippet for this,
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"Date >= %@ AND
Date <= %@", startDate,endDate];
NSArray *filter = [arrayEvents filteredArrayUsingPredicate:predicate];
Test filtration:
Case 1:
NSString *startDate = @"01/07/14";
NSString *endDate = @"31/07/2014";
Output: All events (rows).
Case 2:
NSString *startDate = @"20/07/14";
NSString *endDate = @"31/07/2014";
Output: Last four events (rows).
Case 3:
NSString *startDate = @"11/07/14";
NSString *endDate = @"20/07/2014";
Output: Only 2nd event (row).
Case 4:
NSString *startDate = @"01/08/14";
NSString *endDate = @"31/08/2014";
Output: All events (rows).
Conclusion:
Case 1, 2 and 3 is correct, where Case 4 is incorrect.
Notes:
- Date is of type
NSString
- Date format is date-month-year (i.e. dd/MM/yyyy)
- Same result even date is formatted with
- hyphen
instead of/ (forward slash)
- Same result even if we changed date format month-date-year (i.e. MM/dd/yyyy)
Some one please help me what I am doing wrong here? Anything that I'm missing? I know there's few other questions but none of which helped me.
回答1:
You need to change your datatype to date (what even makes most sense here). Your tests pass by time, cause they exactly match one string and your predicate contains equals. So if you would just query for < and > no result would be returned in each "test"
Then your snippet
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"Date >= %@ AND
Date <= %@", startDate,endDate];
NSArray *filter = [arrayEvents filteredArrayUsingPredicate:predicate];
works as expected. There is no way to do that with strings as it would require a date formatter to parse the date from the string and compare that. This would be absolutely inefficient. So if you really want to filter this, create a instance of NSDateFormatter and run through each Dictionary. Grab out the date and compare that new formatted date to your start and end date. If it is in between add it to the result array (also need to create this before).
NSMutableArray* result = [NSMutableArray array];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
formatter.dateFormat = @"dd/MM/yy";
for (NSDictionary *dict in yourArray) {
NSString *dateString = dict[@"Date"];
NSDate *date = [formatter dateFromString:dateString];
if ([date compare:startDate] > 0 && [date compare:endDate] < 0) {
[result add:dict];
}
}
//use the filtered array here
回答2:
I've not used NSPredicate
much but the concept of comparison of dates within strings is almost certainly not supported. If you use the right type to represent your data then you will have more success I'm sure. The right data type being NSDate
.
回答3:
You cannot compare two strings like that. You can use timestamp instead of String then you can compare the same.
来源:https://stackoverflow.com/questions/24669902/nspredicate-to-filter-between-two-dates-of-nsstring-type