web-dev-qa-db-ja.com

CoreData述語の日付の比較

ユーザーselectedDate(NSDate)に一致するエンティティ内のすべてのオブジェクトをフェッチしようとしています。 Core Dataコードは問題ありませんが、私の述語は0の結果を返し続けます。データベース内の日付は、ユーザーが選択したものと同じです。

SelectedDateは、述語を使用するエンティティの日付とどのように比較する必要がありますか?

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(eDate = %@)", selectedDate];
14
user2228755

あなたの述語は問題ないようです。

ただし、結果がゼロであることがわかった理由は、日付が完全に同じではない可能性があります。

例えば:

05/04/2012 13:37:0005/04/2012 13:37:01と一致しません。これは、これら2つの値が完全に同じではないためです。

日付(日、月、年)と時刻を確認しますか?

日付のみを確認したい場合は、開始日と終了日を作成し、ユーザーが選択した日付を基準として比較する必要があります。

これに似たもので、00:00:00の日付と時刻を作成する必要があります。

//gather current calendar
NSCalendar *calendar = [NSCalendar currentCalendar];

//gather date components from date
NSDateComponents *dateComponents = [calendar components:(NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit) fromDate:[NSDate date]];

//set date components
[dateComponents setHour:0];
[dateComponents setMinute:0];
[dateComponents setSecond:0];

//return date relative from date
return [calendar dateFromComponents:dateComponents];

時間、分、秒を23:59:59に設定して別の日付を作成し、ユーザーが選択した日付がこれらの範囲内にあることを確認します。

[NSPredicate predicateWithFormat:@"date BETWEEN %@", [NSArray arrayWithObjects:startOfDay, endOfDay, nil]]
23
CaptainRedmuff

人間のコミュニケーションでは、日付は日と同じであることがよくありますが、NSDateオブジェクトと同じではありません。NSDateは特定の瞬間を表します。ほんの数秒で異なる日付は等しくありません。そして実際には、これはカレンダーシステムごとに異なるため、日、月、年をまったく表していません。

同じ分、時間、日…の日付が等しいかどうかを自分で定義する必要があります。したがって、基本的には、プログラムにあいまいさを許容するように教える必要があります。

微細な解像度についてはこちら

NSDate *startDate = ....;
NSTimeInterval length;

[[NSCalendar currentCalendar] rangeOfUnit:NSMinuteCalendarUnit 
                                startDate:&startDate
                                 interval:&length 
                                  forDate:startDate];

NSDate *endDate = [startDate dateByAddingTimeInterval:length];

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(eDate >= %@) AND (eDate < %@)", startDate, endDate];

同じ日の日付(タイムゾーンと夏時間に対応)の場合は、次のように変更します。

[[NSCalendar currentCalendar] rangeOfUnit:NSDayCalendarUnit 
                                startDate:&startDate
                                 interval:&length 
                                  forDate:startDate];
12
vikingosegundo

受け入れられた回答にいくつかの変更を加え、iOS 8APIを使用して時間オフセット付きの日付を作成することができます。コード:

NSCalendar *calendar = [[FFSharedCalendar singleton] getGregorianCalendar];
NSDate *startOfDay = [calendar dateBySettingHour:0 minute:0 second:0 ofDate:[NSDate date] options:0];
NSDate *endOfDay = [calendar dateBySettingHour:23 minute:59 second:59 ofDate:[NSDate date] options:0];

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"createdAt > %@ AND createdAt < %@", startOfDay, endOfDay];
NSArray* plans = [Plan MR_findAllWithPredicate:predicate];

それが誰かを助けることを願っています

2
halbano

私は最近、この同じ問題を解決するためにしばらく時間を費やし、以下を解決しました。現在、iOS8以降用に更新されています...

NSDate *dateDay = nil;
NSDate *dateDayStart = nil;
NSDate *dateDayNext = nil;

dateDay = <<USER_INPUT>>;  //for example - selectedDate

dateDayStart = [[NSCalendar currentCalendar] startOfDayForDate:dateDay];

//  dateDayNext EITHER
dateDayNext = [dateDayStart dateByAddingTimeInterval:(24 * 60 * 60)];

//  dateDayNext OR
NSDateComponents *dateComponentDay = nil;
dateComponentDay = [[NSDateComponents alloc] init];
[dateComponentDay setDay:1];
dateDayNext = [[NSCalendar currentCalendar] dateByAddingComponents:dateComponentDay
                                                            toDate:dateDayStart
                                                           options:NSCalendarMatchNextTime];

...そしてコアデータのNSPredicateNSFetchRequest(他の回答ですでに示したように)...

[NSPredicate predicateWithFormat:@"(dateAttribute >= %@) AND (dateAttribute < %@)", dateDayStart, dateDayNext]]
0
andrewbuilder