DATEADD 的 NSPredicate 语法?
Posted
技术标签:
【中文标题】DATEADD 的 NSPredicate 语法?【英文标题】:NSPredicate syntax for DATEADD? 【发布时间】:2010-11-13 04:36:27 【问题描述】:有没有办法在 NSPredicate 上执行 DateAdd 或 DateDiff 函数? 谢谢, 何塞。
【问题讨论】:
+1,但是伙计和我打算写一篇博文来解决这个问题......谢谢你偷走了我的风头:P ;) 【参考方案1】:其实有!这是一种迂回的做法,因为NSPredicate
不直接支持它(即,您不能只将+ anInterval
转换为NSDate
)。幸运的是,你可以做到,幸运的是,我大约 2 天前才弄明白。
澄清一下:我假设您要求类似:“一个对象具有date
属性。我想看看这个date
属性是否是另一个日期之前/之后的任意间隔”。如果这就是你的意思,那么是的,你可以做到。如果这不是您的意思,请澄清您的问题。
我们开始吧。在这个例子中,我们将假设我们要评估这个谓词的对象有一个名为date
的属性,它返回一个NSDate
。我们将查看该日期是否至少比另一个日期早 1 天。我们可以通过几种不同的方式进行比较:
date + 1 day is before comparisonDate
date is before comparisonDate - 1 day
我将采用第一种方法:
NSDate * comparisonDate = ...; //an arbitrary NSDate object, against which we're going to be doing our comparison
NSTimeInterval interval = 86400; //the number of seconds you want add or subtract.
NSPredicate * p = [NSPredicate predicateWithFormat:@"CAST(CAST(date, 'NSNumber') + %f, 'NSDate') < %@", interval, comparisonDate];
发生了什么:
要使其工作,我们可以将CAST()
日期对象转换为NSNumber
。这会将NSDate
转换为NSNumber
,这是距参考时间点(例如1970 年1 月1 日或其他任何时间)的一些秒数。我们对这个数字加上或减去我们的区间,然后将新数字转换回NSDate
。然后我们可以使用常规比较运算符将新日期与比较日期进行比较。
这个想法有几个不同的变体,但它们都需要将NSDate
转换为一个数字(或将一个数字转换为NSDate
)以获得它的时间间隔。
狡猾,嗯?
编辑
如果 Core Data 抱怨谓词的构造,请尝试反转:
NSDate * comparisonDate = ...;
NSTimeInterval interval = 86400;
NSPredicate * p = [NSPredicate predicateWithFormat:@"date < CAST(CAST(%@, 'NSNumber') - %f, 'NSDate')", comparisonDate, interval];
编辑#2
牧师偷来的雷声:http://tumblr.com/xqorqjfrz
【讨论】:
戴夫非常感谢,不要取消我帐户上的博客。我很想知道您是如何想出这个解决方案的? 不幸的是,它不适用于 coredata,当将谓词设置为实体时,我得到一个“不支持的功能”异常...... 我尝试了两种创建 NSPredicate 的形式,但它们似乎都不起作用。即使是最简单的表达式,它似乎也会抛出错误: NSPredicate * pred = [NSPredicate predicateWithFormat:@"now() != 0"];不断收到“*由于未捕获的异常'NSInvalidArgumentException'而终止应用程序,原因:'Unsupported function expression now()'” 这很聪明,但你为什么不直接调整比较日期 +/- 1 天并避免混乱,例如不要将明天(今天 + 1 天)与 30 天前进行比较,而是将今天与 31 天前进行比较。那么它就变成了一个简单的谓词比较 [... @"date以上是关于DATEADD 的 NSPredicate 语法?的主要内容,如果未能解决你的问题,请参考以下文章
NSPredicate 语法以排除给定的 NSManagedObject