我有两个NSDate
s:
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
)。
我也试过像这样构建谓词:
NSPredicate *dateStartPredicate = [NSPredicate predicateWithFormat:@"createdDate >= %@", rangeStart];
NSPredicate *dateEndPredicate = [NSPredicate predicateWithFormat:@"createdDate <= %@", rangeEnd];
NSPredicate *finalPredicate = [NSCompoundPredicate andPredicateWithSubpredicates:[NSArray arrayWithObjects:dateStartPredicate, dateEndPredicate, nil]];
但我得到的结果相同。难道我做错了什么?这实际上是预期的行为吗?如果是,如何将rangeEnd
设置为第二天?
由于
答案 0 :(得分:6)
NSDate
个对象也包括时间。当您将没有时间的日期传递给dateFromString:
方法时,将假定相应日期的午夜,即只有午夜发生的项目将以小于或等于表达式返回true
。 / p>
有两种常见的解决方法:
rangeEnd
,并使用“小于”而不是“小于或等于”,或rangeEnd
日期(这不太理想,因为您需要在长字符串中指定时间,或者错过当天最后一秒发生的项目)。 / LI>
以下是使用第一种方法的方法:
request.predicate = [NSPredicate
predicateWithFormat:@"createdDate >= %@ AND createdDate < %@"
, rangeStart
, [rangeEnd dateByAddingTimeInterval:60*60*24]
];
答案 1 :(得分:2)
请记住,即使类的名称是NSDate,这些对象也代表特定的时间点(不是一整天)。 rangeEnd
设定为10月4日午夜。由于午夜是当天的第一个瞬间,因此只有当天午夜的活动才会包含在您的搜索结果中。将rangeEnd
移至第二天,如下所示,您应该会得到您期望的结果。
NSCalendar* calendar = [NSCalendar autoupdatingCurrentCalendar];
NSDateComponents* components = [[NSDateComponents alloc] init];
components.day = 1;
NSDate* newDate = [calendar dateByAddingComponents:components toDate:rangeEnd options: 0];