NSPredicate 在 NSString 类型的两个日期之间进行过滤

Posted

技术标签:

【中文标题】NSPredicate 在 NSString 类型的两个日期之间进行过滤【英文标题】:NSPredicate to filter between two dates of NSString type 【发布时间】:2014-07-10 06:34:08 【问题描述】:

我有一些数据(如NSMutableArray 中的NSDictionary),示例数据如下,

将每一行视为NSDictionary,整个表是一个包含事件的NSMutableArray

我想要两个日期之间的结果,所以我使用NSPredicate 过滤我的数据。


这是我的代码 sn-p,

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"Date >=  %@ AND
Date <=  %@", startDate,endDate];

NSArray *filter = [arrayEvents filteredArrayUsingPredicate:predicate];

测试过滤


案例 1:

NSString *startDate = @"01/07/14";
NSString *endDate = @"31/07/2014";

输出: 所有事件(行)。


案例 2:

NSString *startDate = @"20/07/14";
NSString *endDate = @"31/07/2014";

输出: 最后四个事件(行)。


案例 3:

NSString *startDate = @"11/07/14";
NSString *endDate = @"20/07/2014";

输出: 只有第二个事件(行)。


案例 4:

NSString *startDate = @"01/08/14";
NSString *endDate = @"31/08/2014";

输出: 所有事件(行)。


结论:

案例 1、2 和 3 正确,案例 4 不正确。


注意事项:

日期类型为NSString 日期格式为日-月-年(即 dd/MM/yyyy) 即使日期格式为- hyphen 而不是/ (forward slash),结果相同 即使我们更改了日期格式月-日-年(即 MM/dd/yyyy),结果也相同

有人请帮助我我在这里做错了什么?有什么我想念的吗?我知道还有一些其他问题,但没有一个对我有帮助。

【问题讨论】:

我没有经常使用NSPredicate,但几乎可以肯定不支持字符串中日期比较的概念。如果您使用正确的类型来表示您的数据,那么我相信您会取得更大的成功。正确的数据类型是NSDate 【参考方案1】:

您需要将您的数据类型更改为最新(甚至在这里最有意义)。 您的测试通过时间,因为它们完全匹配一个字符串并且您的谓词包含等于。 因此,如果您只查询 在每个“测试”中都不会返回任何结果

然后你的sn-p

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"Date >=  %@ AND
Date <=  %@", startDate,endDate];

NSArray *filter = [arrayEvents filteredArrayUsingPredicate:predicate];

按预期工作。没有办法用字符串来做到这一点,因为它需要一个日期格式化程序来解析字符串中的日期并进行比较。这绝对是低效的。 因此,如果您真的想过滤它,请创建一个 NSDateFormatter 实例并运行每个 Dictionary。找出日期并将新格式化的日期与您的开始和结束日期进行比较。如果介于两者之间,则将其添加到结果数组中(之前也需要创建它)。

NSMutableArray* result = [NSMutableArray array];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
formatter.dateFormat = @"dd/MM/yy";
for (NSDictionary *dict in yourArray) 
    NSString *dateString = dict[@"Date"];
    NSDate *date = [formatter dateFromString:dateString];
    if ([date compare:startDate] > 0 && [date compare:endDate] < 0) 
       [result add:dict];
    

//这里使用过滤后的数组

【讨论】:

@lucaswelte 是否可以在 NSPredicate 本身中包含日期格式化程序解析。尽管您说这效率低下,但我愿意在我的情况下对其进行测试并自己决定。 这是不可能的。但是您可以做的是为 NSDate 编写一个扩展(类别)或者可能是最好的解决方案,只需创建一个允许将日期格式化为字符串的单例。作为单例,它可以从任何地方访问,当 NSDateFormatter 是这个单例的属性时,它会在每次转换中重用。【参考方案2】:

我没有经常使用NSPredicate,但几乎可以肯定不支持字符串中日期比较的概念。如果您使用正确的类型来表示您的数据,那么我相信您会取得更大的成功。正确的数据类型是NSDate

【讨论】:

【参考方案3】:

你不能像这样比较两个字符串。您可以使用时间戳代替字符串,然后您可以比较。

【讨论】:

以上是关于NSPredicate 在 NSString 类型的两个日期之间进行过滤的主要内容,如果未能解决你的问题,请参考以下文章

NSPredicate 中 NSString 的问题

NSPredicate 与 NSString 发生奇怪的崩溃

NSPredicate 与 NSString:查找超字符串哪个更好/更快?

ios 如何正确使用 NSPredicate 来匹配 Core Data 的 NSString?

NSPredicate 问题

在 NSPredicate 中使用 ALL/ANY/NONE