两个date之间的NSPredicate范围不能按预期工作

我有这两个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"]; 

而这个谓词:

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

但是即使谓词的第二部分特别使用<=它直到前一天(即10/03/2013 )才返回对象。

我也尝试构build这样的谓词:

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

但是我得到了同样的结果。 难道我做错了什么? 这实际上是预期的行为? 如果是的话,如何设置范围到第二天?

谢谢

NSDate对象也包含时间。 当你没有时间给dateFromString:方法传递一个date时,假定相应日子的午夜,也就是说,只有在午夜发生的项目才会在小于或等于expression式中返回true

有两种常见的解决方法:

  • 添加一天到rangeEnd ,并使用“小于”而不是“小于或等于”,或者
  • 将时间添加到rangeEnddate(这是不理想的,因为您需要指定一个长string的时间,或错过在一天的最后一秒发生的项目)。

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

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

请记住,即使类的名称是NSDate,这些对象代表特定的时间点(而不是一整天)。 rangeEnd被设定为10月4日的午夜。 由于午夜是当天的第一个时刻,所以只有当天午夜的事件才会包含在您的结果中。 移动范围结束如下图所示的第二天,你应该得到你期望的结果。

 NSCalendar* calendar = [NSCalendar autoupdatingCurrentCalendar]; NSDateComponents* components = [[NSDateComponents alloc] init]; components.day = 1; NSDate* newDate = [calendar dateByAddingComponents:components toDate:rangeEnd options: 0];