Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to filter Realm objects via an NSDate property

I'm trying to filter Realm objects to find those with createdAt dates less than year ago:

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

I'm getting the following error:

Expected object of type date for property 'createdAt' on object of type 'TaskList', but received: '2015-03-19 21:00:00 +0000'

How do I fix this? It also looks like the date and time value are adjusted to time zone. How can I make sure the date is really the end of the day?

like image 201
alexey Avatar asked Mar 18 '16 22:03

alexey


1 Answers

The immediate problem is that you're using Swift's string interpolation to build your predicate rather than using NSPredicate's argument substitution. This results in your predicate being something like:

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

This is attempting to compare createdAt, a date, with a string literal. Using NSPredicate's argument substitution would look like:

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

Note that the way you're computing the date isn't correct in the face of leap days, leap seconds, discontinuities due to daylight savings, and so forth. You should use NSCalendar's methods for date math rather than doing math with magic constants:

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

Keep in mind that an NSDate represents a single point in time, independent of any time zone. The default formatting of NSDate, used when -[NSDate description] is called, happens to format the date in UTC. If you'd like to format the date to a string using a different time zone, you can use NSDateFormatter and set the time zone explicitly.

like image 124
bdash Avatar answered Sep 21 '22 18:09

bdash