Использование NSPredicate для получения точного NSDate из NSManagedObjectContect - PullRequest
7 голосов
/ 21 ноября 2010

Я пытаюсь получить результаты моей сущности 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 у меня есть четыре записи с датами. Если я использую «<=» вместо «==», я получаю результаты с датой, меньшей той, которую я прошел, включая ту, которую я хочу получить. Почему я не могу получить одну дату с оператором "=="? Может ли это быть связано с точностью моих дат? </p>

Спасибо!

Ответы [ 3 ]

3 голосов
/ 22 ноября 2010

Это та же проблема, что проверки на равенство с плавающей точкой по своей сути небезопасны. По мере того как значения с плавающей точкой передаются, конвертируются, используются в арифметике и т. Д., Они постепенно теряют точность. Возможно, вам придется использовать более сложный предикат, который вместо этого проверяет даты в пределах определенного допуска; например,

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

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

, который даст вам любые объекты, соответствующие вашей дате плюс или минус одна секунда.

3 голосов
/ 21 ноября 2010

Первый вопрос: почему два числа не совпадают?

Внутренне, NSDate, похоже, хранит метку времени относительно 1 января 2001 года, а не 1 января 1970 года. Число 311957172.210091, вероятно, является числом секунд с 01 января 2001 года.

Почему я не могу получить одну дату с оператором "=="? Может ли это быть связано с точностью моих дат?

Я не знаю. Вы проверяли файл SQLite напрямую, чтобы увидеть, какие временные метки там хранятся?

1 голос
/ 21 ноября 2010

На ваш первый вопрос, держу пари, числа будут совпадать, если вы использовали [self.timestamp timeIntervalSinceReferenceDate] вместо 1970 года.

Что касается вашего второго вопроса, я догадываюсь, что дата в хранилище управляемых объектов не совсем совпадает с self.timestamp. Например, может ли быть, что сохраненная дата содержит только день, а не время? Возможно, вам придется выполнить некоторое округление, чтобы сопоставить их.

...