两个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
,并使用“小于”而不是“小于或等于”,或者 - 将时间添加到
rangeEnd
date(这是不理想的,因为您需要指定一个长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];