使用 NSPredicate 从 NSManagedObjectContect 获取准确的 NSDate

发布于 2024-10-03 18:37:03 字数 898 浏览 1 评论 0原文

我正在尝试获取实体“MeterReading”的结果,该实体有两个属性:“时间戳”和“读数”。 “时间戳”是一个 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 中,我有四个带有日期的条目。如果我使用“<=”而不是“==”,我确实会得到日期小于我通过的日期的结果,包括我想要的日期。为什么我无法使用“==”运算符获取单个日期?这可能与我的日期精度有关吗?

谢谢!

I'm trying to fetch results of my entity "MeterReading", which has two properties, "timestamp" and "reading". "timestamp" is an NSDate. I'm now trying to fetch 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 passed to another ViewController beforehand, the NSLog shows:

1290264372.210091

The NSPredicate logs

timestamp == CAST(311957172.210091, "NSDate")

First question: Why aren't the two numbers the same?

Second and more important question: In the ManagedContext, I have four entries with dates. If I use "<=" instead of "==", I do get results with a date smaller than the one I passed, including the one I want to have. Why can't I get the one single date with the "==" operator? Can this be related to precision of my dates?

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

临走之时 2024-10-10 18:37:03

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

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

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

这将为您提供与您的日期加或减一秒匹配的任何对象。

This is the same issue as floating-point equality checks being inherently unsafe. As floating-point values get passed around, converted, used in arithmetic, etc., they lose accuracy bit by bit. You may have to use a more complex predicate that instead checks for dates within a certain tolerance; for instance,

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

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

which would get you any objects matching your date plus or minus one second.

故事和酒 2024-10-10 18:37:03

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

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

为什么我无法使用“==”运算符获取单个日期?这可能与我的日期精度有关吗?

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

First question: Why aren't the two numbers the same?

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

Why can't I get the one single date with the "==" operator? Can this be related to precision of my dates?

I don't know. Have you inspected the SQLite file directly to see which timestamps are stored there?

穿越时光隧道 2024-10-10 18:37:03

对于你的第一个问题,我敢打赌,如果你使用 [self.timestamp timeIntervalSinceReferenceDate] 而不是自 1970 年以来,数字将会匹配。对于

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

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

For your second question, my hunch is that the date in the managed object storage is not exactly the same as self.timestamp. For instance, could it be that the stored date only contains a day and not time? You might need to do some rounding to get those to match.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文