NSPredicate两个日期之间的范围没有按预期工作

Jan*_*Jan 4 iphone objective-c nspredicate ipad ios

我有这两个NSDate:

NSDateFormatter *df = [[NSDateFormatter alloc] init];
[df setDateFormat:@"MM/dd/yyyy"];
NSDate *rangeStart = [df dateFromString: @"03/03/2013"];
NSDate *rangeEnd = [df dateFromString: @"10/04/2013"];
Run Code Online (Sandbox Code Playgroud)

这个谓词:

request.predicate = [NSPredicate predicateWithFormat:@"createdDate >= %@ AND createdDate <= %@", rangeStart, rangeEnd];
Run Code Online (Sandbox Code Playgroud)

但即使谓词的第二部分专门使用<=它,它也会将对象返回到前一天(即10/03/2013).

我也试过构建这样的谓词:

NSPredicate *dateStartPredicate = [NSPredicate predicateWithFormat:@"createdDate >= %@", rangeStart];
NSPredicate *dateEndPredicate = [NSPredicate predicateWithFormat:@"createdDate <= %@", rangeEnd];
NSPredicate *finalPredicate = [NSCompoundPredicate andPredicateWithSubpredicates:[NSArray arrayWithObjects:dateStartPredicate, dateEndPredicate, nil]]; 
Run Code Online (Sandbox Code Playgroud)

但我得到的结果相同.难道我做错了什么?这实际上是预期的行为吗?如果是,怎么设置rangeEnd到第二天?

谢谢

das*_*ght 6

NSDate对象也包括时间.当您将没有时间的日期传递给dateFromString:方法时,将假定相应日期的午夜,即仅在午夜发生的项目将以true小于或等于表达式返回.

有两种常见的解决方法:

  • 添加一天rangeEnd,并使用"小于"而不是"小于或等于",或
  • 将时间添加到rangeEnd日期(这不是理想的,因为您需要在长字符串中指定时间,或者错过当天最后一秒发生的项目).

以下是如何使用第一种方法:

request.predicate = [NSPredicate
    predicateWithFormat:@"createdDate >= %@ AND createdDate < %@"
    , rangeStart
    , [rangeEnd dateByAddingTimeInterval:60*60*24]
];
Run Code Online (Sandbox Code Playgroud)