Using NSPredicate to Get Exact NSDate from NSManagedObjectContect

I am trying to get the results of my MeterReading entity, which has two properties: timestamp and read. "timestamp" is an NSDate. Now I am trying to get an object with an exact date.

NSFetchRequest *request = [[NSFetchRequest alloc] init]; NSEntityDescription *entity = [NSEntityDescription entityForName:@"MeterReading" inManagedObjectContext:context]; [request setEntity:entity]; NSLog(@"%f", [self.timestamp timeIntervalSince1970]); NSPredicate *pre = [NSPredicate predicateWithFormat:@"timestamp == %@", self.timestamp]; NSLog(@"%@", pre); [request setPredicate:pre]; 

Now, self.timestamp is previously passed to another ViewController, the NSLog shows:

+1290264372,210091

NSPredicate Logs

timestamp == CAST (311957172.210091, "NSDate")

First question: why do the two numbers not match?

The second and more important question: in ManagedContext, I have four records with dates. If I use "<=" instead of "==", I get results with a date that is less than the one I passed, including the one I want to have. Why can't I get a single date with the operator "=="? Could this be due to the accuracy of my dates?

Thanks!

+7
objective-c iphone fetch nsdate nspredicate
source share
3 answers

This is the same problem as checking for floating point equality, which is essentially unsafe. Since floating point values ​​are transferred, converted, used in arithmetic, etc., they gradually lose accuracy. You may need to use a more complex predicate, which instead checks for dates within a certain tolerance; eg,

 NSArray *timestamps = [NSArray arrayWithObjects: [self.timestamp dateByAddingTimeInterval:-1], [self.timestamp dateByAddingTimeInterval:1], nil ]; NSPredicate *pre = [NSPredicate predicateWithFormat:@"timestamp BETWEEN %@", timestamps]; 

which will provide you with any objects matching your date plus minus one second.

+3
source share

First question: why do the two numbers not match?

Inside, NSDate seems to store a timestamp relative to January 1, 2001, and not January 1, 1970. The number 311957172.210091 is probably the number of seconds since 01/01/2001.

Why can't I get a single date with the operator "=="? Could this be due to the accuracy of my dates?

I dont know. Have you checked the SQLite file directly to see what timestamps are stored there?

+3
source share

For your first question, I'm sure the numbers will match if you used [self.timestamp timeIntervalSinceReferenceDate] instead of 1970.

For your second question, my hunch is that the date in the managed object repository is not quite the same as self.timestamp. For example, could it be that the stored date contains only the day, not the time? You may need to round to match.

+1
source share

All Articles