Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
879 views
in Technique[技术] by (71.8m points)

iphone - NSPredicate for range between two dates is not working as expected

I have these two NSDates:

NSDateFormatter *df = [[NSDateFormatter alloc] init];
[df setDateFormat:@"MM/dd/yyyy"];
NSDate *rangeStart = [df dateFromString: @"03/03/2013"];
NSDate *rangeEnd = [df dateFromString: @"10/04/2013"];

And this predicate:

request.predicate = [NSPredicate predicateWithFormat:@"createdDate >= %@ AND createdDate <= %@", rangeStart, rangeEnd];

But even though the second part of the predicate specifically uses a <= it is returning objects up until the day before (that is 10/03/2013).

I also tried constructing the predicate like this:

NSPredicate *dateStartPredicate = [NSPredicate predicateWithFormat:@"createdDate >= %@", rangeStart];
NSPredicate *dateEndPredicate = [NSPredicate predicateWithFormat:@"createdDate <= %@", rangeEnd];
NSPredicate *finalPredicate = [NSCompoundPredicate andPredicateWithSubpredicates:[NSArray arrayWithObjects:dateStartPredicate, dateEndPredicate, nil]]; 

But I'm getting the same results. Am I doing something wrong? Is this actually the expected behavior? If it is, how can set the rangeEnd to the next day?

Thanks

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

NSDate objects include the time as well. When you pass a date with no time to the dateFromString: method, the midnight of the corresponding day is assumed, i.e. only the items that happen on midnight would return true in the less than or equal expression.

There are two common ways of solving it:

  • Add one day to rangeEnd, and use "less than" instead of "less than or equal", or
  • Add the time to the rangeEnd date (this is not ideal, because you would either need to specify the time in a long string, or miss the items that happened on the last second of the day).

Here is how to use the first approach:

request.predicate = [NSPredicate
    predicateWithFormat:@"createdDate >= %@ AND createdDate < %@"
    , rangeStart
    , [rangeEnd dateByAddingTimeInterval:60*60*24]
];

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

57.0k users

...