使用日期作为谓词时 NSFetchRequest 失败

NSFetchRequest fails when using date as predicate

我正在尝试从创建的核心数据实体中获取所有记录 "today",我在实体中有一个名为 createdDate 的字段,它使用以下设备的本地时区将日期存储为字符串格式

2017-06-26T11:06:43+08:00

我创建了以下日期字符串用于比较:

NSDateFormatter *dateFormatterDayOnly = [[NSDateFormatter alloc] init];
    [dateFormatterDayOnly setDateFormat:@"yyyy-MM-dd"];
    [dateFormatterDayOnly setTimeZone:[NSTimeZone localTimeZone]];

    NSString *todaysDate = [dateFormatterDayOnly stringFromDate:[NSDate date]];

调试告诉我谓词看起来没问题,如下所示

2017-06-26 11:33:22.277 NWMobileTill[1842:482539] -[EodView tillTotalCashIn] todaysDate:2017-06-26

然后我按如下方式创建谓词

NSPredicate *predicateTodaysDate = [NSPredicate predicateWithFormat:@"createdDate like[cd] %@", todaysDate];

    fetchPts.predicate = predicateTodaysDate;

    NSArray *todaysTendersArray = [[context executeFetchRequest:fetchPts error:&errorPts] mutableCopy];

但是这个returns 0点击

我原以为这会匹配今天创建的所有内容。

我需要更改什么才能使 return 今天创建所有记录?

而不是 like[cd] 使用 BEGINSWITH

[NSPredicate predicateWithFormat:@"createdDate BEGINSWITH %@", todaysDate];

或正则表达式求值:

NSString* regex = [NSString stringWithFormat:@"^%@.*$", todaysDate];
[NSPredicate predicateWithFormat:@"createdDate MATCHES %@", regex];

将日期对象存储为字符串错误。这不是一点错误。这不是'有道理的人会不同意错。完全错了。

作为字符串,您无法比较哪个更大。你不能 select 一个范围。您不能按日期排序。最重要的是,您认为字符串会做得更好的一件事——将日期显示为字符串——也更难!由于本地化,您必须将字符串解析为日期,然后再解析为正确的本地化字符串。

如果您还没有发布您的应用程序,只需更改核心数据模型中的类型,删除该应用程序,然后重新安装。确保其他所有人也删除该应用程序,否则应用程序会因他们而崩溃。

如果您已经发布了您的应用,请使用另一个 属性 创建一个新的模型版本,并将 createdDate 作为日期。当应用程序启动时(但不在应用程序委托中 - 因为它可能需要超过 5 秒,如果启动,则 OS 将强制退出应用程序)遍历数据库并解析所有 createdDate 字符串并将它们放入进入 createdDate 日期字段。

当值为 a 时进行搜索 date 获取日期的开始和结束并搜索介于两者之间的值。

NSDate* startOfDay = [self.calendar startOfDayForDate:[NSDate date]];
NSDate* endOfDay = [self.calendar dateByAddingUnit:NSCalendarUnitDay value:1 toDate:startOfDay options:0];
NSPredicate *predicate = [NSCompoundPredicate andPredicateWithSubpredicates:@[[NSPredicate predicateWithFormat:@"createdDate > %@", startOfDay],[NSPredicate predicateWithFormat:@"createdDate < %@", endOfDay]]];