2010-11-21 7 views
7

"MeterReading"エンティティの結果を取得しようとしていますが、 "timestamp"と "reading"という2つのプロパティがあります。 「タイムスタンプ」はNSDateです。私は今、正確な日付のオブジェクトを取得しようとしています。NSPredicateを使用してNSManagedObjectContectから正確な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")

最初の質問:なぜ2つの数字が同じではないのですか?

第2の重要な質問:ManagedContextでは、日付付きの4つのエントリがあります。 「==」の代わりに「< =」を使用すると、渡した日付よりも小さい日付の結果が得られます。なぜ "=="演算子で1つの日付を得ることができないのですか?これは私の日付の精度に関連することができますか?

ありがとうございます!

答えて

3

これは、本質的に安全でない浮動小数点等価チェックと同じ問題です。浮動小数点値が渡されたり、変換されたり、算術などで使用されると、ビットごとに精度が失われます。特定の許容範囲内の日付をチェックするより複雑な述語を使用する必要があります。たとえば、

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

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

となります。これにより、日付にプラスマイナス1秒の一致するオブジェクトが表示されます。

+0

、ほとんど働いて、ありがとう!配列を渡すとエラーが発生しましたが、2つのnsdateを手動で述語に渡しました。 :) – denbec

+0

おっと、申し訳ありません!しかし、助けてくれてうれしい。 –

+0

この例は、コアデータでは機能しません。あなたは次のようなものを使う必要があります:http://zdam.posterous.com/core-data-fetch-by-date – SpaceTrucker

3

最初の質問:なぜ2つの数字が同じではないのですか?

内部的には、NSDateは2001年1月1日にタイムスタンプを相対格納するようではなく、1970年1月1日数311957172.210091は、おそらく2001年1月1日からの秒数です。

"=="演算子で1つの日付を取得できないのはなぜですか?これは私の日付の精度に関連することができますか?

わかりません。 SQLiteファイルを直接調べてそこに保存されているタイムスタンプを確認しましたか?あなたの最初の質問については

+0

私は自分の店からタイムスタンプを取得しています。それを別のビューコントローラに渡し、そこで削除しようとしています。したがって、私は同じオブジェクトを取得しようとしています。私はあらかじめタイムスタンプを渡しました。それは奇妙なことです。 管理対象オブジェクトを事前に取得せずに削除する方法はありますか? – denbec

+0

なぜオブジェクト自体ではなくタイムスタンプを渡しますか?もう一度フェッチする必要はありません。 –

1

あなたは2番目の質問について、1970年

以来[self.timestamp timeIntervalSinceReferenceDate]の代わりを使用した場合、私は数字が一致する賭け、私の勘では、管理対象オブジェクトストレージの日付が全く同じではないということですself.timestamp。たとえば、保存された日付には時間ではなく1日だけが含まれていてもかまいませんか?一致させるには丸めを行う必要があるかもしれません。

+0

実際には、管理対象オブジェクトからタイムスタンプまたは日付を直接使用して別のビューコントローラに渡したり、他のものを実行したり、再度削除したりします。したがって、私はコンテキストからそれを削除するオブジェクトが必要です、そして、私は再びそれをフェッチする前にオブジェクトを削除する他の方法を知らない。 これは、私が使用しているのと同じ日付でなければなりません。 – denbec

関連する問題