如何通过 NSDate 属性过滤 Realm 对象

Posted

技术标签:

【中文标题】如何通过 NSDate 属性过滤 Realm 对象【英文标题】:How to filter Realm objects via an NSDate property 【发布时间】:2016-03-18 22:31:22 【问题描述】:

我正在尝试过滤 Realm 对象以查找日期少于一年前的 createdAt 对象:

let datex = NSCalendar.currentCalendar().startOfDayForDate(NSDate()).dateByAddingTimeInterval(-1*365*24*60*60)
let list = RealmDB.objects(TaskList).filter("createdAt <= '\(datex)'")

我收到以下错误:

类型为“TaskList”的对象的属性“createdAt”的预期类型为日期对象,但收到:“2015-03-19 21:00:00 +0000”

我该如何解决这个问题?看起来日期和时间值也已调整为时区。如何确定日期真的是一天的结束?

【问题讨论】:

【参考方案1】:

直接的问题是您使用 Swift 的字符串插值来构建您的谓词,而不是使用 NSPredicate 的参数替换。这导致您的谓词类似于:

createdAt <= '2015-03-19 07:00:00 +0000'

这是尝试将日期createdAt 与字符串文字进行比较。使用NSPredicate 的参数替换看起来像:

let list = RealmDB.objects(TaskList).filter("createdAt <= %@", datex)

请注意,面对闰日、闰秒、夏令时造成的不连续性等情况,您计算日期的方式是不正确的。您应该使用NSCalendar 的方法进行日期数学运算,而不是使用魔法常数进行数学运算:

let calendar = NSCalender.currentCalendar()
let datex = calendar.dateByAddingUnit(.Year, value: -1, toDate: calendar.startOfDayForDate(NSDate()), options: [.MatchFirst])

请记住,NSDate 代表一个时间点,与任何时区无关。 NSDate 的默认格式(在调用 -[NSDate description] 时使用)恰好将日期格式化为 UTC。如果您想使用不同的时区将日期格式化为字符串,您可以使用NSDateFormatter 并明确设置时区。

【讨论】:

以上是关于如何通过 NSDate 属性过滤 Realm 对象的主要内容,如果未能解决你的问题,请参考以下文章

通过 NSDate 对象属性进行 Swift 过滤

Realm create() 无法将 JSON 字符串解析为 NSDate?

如何在 Realm swift 中过滤为当前日期创建的事件?

使用 Swift 过滤 Realm 对象

在Swift中使用Realm进行过滤,给我一个对象数组,但是当打印一个属性时,它会给我一个空字符串

如何通过数组对象的 NSDate 日期将 NSArray 拆分为 NSDictionary?