使用NSPredicate从NSManagedObjectContect获取精确的NSDate

时间:2010-11-21 12:12:13

标签: iphone objective-c nsdate nspredicate fetch

我正在尝试获取我的实体“MeterReading”的结果,它有两个属性“timestamp”和“reading”。 “timestamp”是一个NSDate。我现在正在尝试获取具有确切日期的对象。

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];

现在,self.timestamp预先传递给另一个ViewController,NSLog显示:

  

1290264372.210091

NSPredicate记录

  

时间戳== CAST(311957172.210091,“NSDate”)

第一个问题:为什么这两个数字不一样?

第二个也是更重要的问题:在ManagedContext中,我有四个带日期的条目。如果我使用“< =”而不是“==”,我会得到日期小于我通过的日期的结果,包括我想要的日期。为什么我不能使用“==”运算符获得单个日期?这可能与我约会​​的精确度有关吗?

谢谢!

3 个答案:

答案 0 :(得分:3)

  

第一个问题:为什么这两个数字不相同?

在内部,NSDate似乎存储了相对于2001年1月1日而不是1970年1月1日的时间戳。数字311957172.210091可能是自01/01/2001以来的秒数。 / p>

  

为什么我不能使用“==”运算符获得单一日期?这可能与我约会​​的精确度有关吗?

我不知道。您是否直接检查过SQLite文件以查看哪些时间戳存储在那里?

答案 1 :(得分:3)

这与浮点相等检查本质上不安全的问题相同。当浮点值传递,转换,用于算术等时,它们会逐位失去准确性。您可能必须使用更复杂的谓词来代替检查某个容差内的日期;例如,

NSArray *timestamps = [NSArray arrayWithObjects:
    [self.timestamp dateByAddingTimeInterval:-1],
    [self.timestamp dateByAddingTimeInterval:1],
    nil
];

NSPredicate *pre = [NSPredicate predicateWithFormat:@"timestamp BETWEEN %@", timestamps];

可以获得与您的日期相加或减去一秒的任何对象。

答案 2 :(得分:1)

对于您的第一个问题,如果您使用[self.timestamp timeIntervalSinceReferenceDate]代替自1970年以来,我打赌这些数字会匹配。

对于第二个问题,我的预感是托管对象存储中的日期与self.timestamp不完全相同。例如,存储的日期可能只包含一天而不是时间吗?您可能需要进行一些舍入以使其匹配。