Swift+RealmSwift中如何在NSPredicate内转换字符串日期并比较
解决Realm中字符串日期的过滤问题
你当前的代码错误在于混淆了NSPredicate的格式化语法与Swift闭包逻辑——Realm的谓词会被转换为底层查询语句,无法直接在表达式里调用DateFormatter这类自定义Swift代码,所以你的写法无法生效。
下面提供两种可行的解决方案:
方案1:修改数据模型(推荐)
直接将nextReview的类型从String改为Date,这是长期来看最可靠、高效的方案:
class RealmCard: Object { // 替换原String类型为Date @Persisted var nextReview: Date? }
修改后即可直接用Date类型做谓词比较,如果需要忽略时间只比较日期,可先获取当天的起始时间:
let today = Date() let startOfToday = Calendar.current.startOfDay(for: today) let datePredicate = NSPredicate(format: "nextReview <= %@", startOfToday) let cardsToReview = Cards.filter(datePredicate).map { $0 }
方案2:字符串格式匹配比较(不修改模型时使用)
由于yyyy-MM-dd格式的字符串字典排序与日期顺序完全一致,可以把当前日期转成相同格式的字符串,直接做字符串比较:
let dateFormatter = DateFormatter() dateFormatter.dateFormat = "yyyy-MM-dd" let todayString = dateFormatter.string(from: Date()) // 利用格式特性直接做字符串比较 let datePredicate = NSPredicate(format: "nextReview <= %@", todayString) let cardsToReview = Cards.filter(datePredicate).map { $0 }
注意事项
- 方案2必须保证所有存储的
nextReview字符串都是严格的yyyy-MM-dd格式,否则会出现比较逻辑错误。 - 方案1的优势更明显:Date类型在Realm中存储更高效,查询性能更好,还能避免字符串格式不统一的问题。
内容的提问来源于stack exchange,提问作者Joseph
相关产品推荐
相关产品推荐

