NSPredicate:フィルタリングによる日NSDate物件
-
21-09-2019 - |
質問
私のコアのデータモデルと NSDate
物件です。たいフィルターのデータベースによります。この溶液を伴わ NSPredicate
, がんがどのように入れます。
私の比較のあり方の日の二 NSDate
s用 NSDateComponents
や NSCalendar
, だが、私はフィルターで NSPredicate
?
もっ成する必要があるカテゴリマ NSManagedObject
サブクラスを返します裸の日だけの年月日です。そしてこれを比較することに NSPredicate
.はこのお勧告、またはものがあるのか、それは何なのか簡単?
解決
nsdate *を与えられた 開始日 と 終了日 およびnsmanagedObjectContext * MOC:
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(date >= %@) AND (date <= %@)", startDate, endDate];
NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease];
[request setEntity:[NSEntityDescription entityForName:@"EntityName" inManagedObjectContext:moc]];
[request setPredicate:predicate];
NSError *error = nil;
NSArray *results = [moc executeFetchRequest:request error:&error];
他のヒント
startdateをセットアップし、上記の回答を終了する方法についての例:
...
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *components = [calendar components:(NSCalendarUnitYear | NSCalendarUnitMonth ) fromDate:[NSDate date]];
//create a date with these components
NSDate *startDate = [calendar dateFromComponents:components];
[components setMonth:1];
[components setDay:0]; //reset the other components
[components setYear:0]; //reset the other components
NSDate *endDate = [calendar dateByAddingComponents:components toDate:startDate options:0];
predicate = [NSPredicate predicateWithFormat:@"((date >= %@) AND (date < %@)) || (date = nil)",startDate,endDate];
...
ここでは、1か月以内にすべてのエントリを探していました。この例では、「nil」の日付 - エンティアを検索する方法も示していることに言及する価値があります。
Swiftで私は次のようなものを手に入れました:
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd"
let date = dateFormatter.dateFromString(predicate)
let calendar = NSCalendar(calendarIdentifier: NSGregorianCalendar)
let components = calendar!.components(
NSCalendarUnit.CalendarUnitYear |
NSCalendarUnit.CalendarUnitMonth |
NSCalendarUnit.CalendarUnitDay |
NSCalendarUnit.CalendarUnitHour |
NSCalendarUnit.CalendarUnitMinute |
NSCalendarUnit.CalendarUnitSecond, fromDate: date!)
components.hour = 00
components.minute = 00
components.second = 00
let startDate = calendar!.dateFromComponents(components)
components.hour = 23
components.minute = 59
components.second = 59
let endDate = calendar!.dateFromComponents(components)
predicate = NSPredicate(format: "day >= %@ AND day =< %@", argumentArray: [startDate!, endDate!])
私はその弦の補間を発見するのに苦労しました "\(this notation)"
nspredicateの日付を比較するためには機能しません。
ま移植するための Glauco Neves 早期2.0包み込んだ内の機能を受けた日付を返します NSPredicate
に対応する日時:
func predicateForDayFromDate(date: NSDate) -> NSPredicate {
let calendar = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)
let components = calendar!.components([.Year, .Month, .Day, .Hour, .Minute, .Second], fromDate: date)
components.hour = 00
components.minute = 00
components.second = 00
let startDate = calendar!.dateFromComponents(components)
components.hour = 23
components.minute = 59
components.second = 59
let endDate = calendar!.dateFromComponents(components)
return NSPredicate(format: "day >= %@ AND day =< %@", argumentArray: [startDate!, endDate!])
}
日付の迅速な3.0拡張機能:
extension Date{
func makeDayPredicate() -> NSPredicate {
let calendar = Calendar.current
var components = calendar.dateComponents([.year, .month, .day, .hour, .minute, .second], from: self)
components.hour = 00
components.minute = 00
components.second = 00
let startDate = calendar.date(from: components)
components.hour = 23
components.minute = 59
components.second = 59
let endDate = calendar.date(from: components)
return NSPredicate(format: "day >= %@ AND day =< %@", argumentArray: [startDate!, endDate!])
}
}
次に使用します:
let fetchReq = NSFetchRequest(entityName: "MyObject")
fetchReq.predicate = myDate.makeDayPredicate()
ラファエルの答えに加えて(信じられないほど便利です、ありがとう!)、Swift 3のために移植。
func predicateForDayFromDate(date: Date) -> NSPredicate {
let calendar = Calendar(identifier: Calendar.Identifier.gregorian)
var components = calendar.dateComponents([.year, .month, .day, .hour, .minute, .second], from: date)
components.hour = 00
components.minute = 00
components.second = 00
let startDate = calendar.date(from: components)
components.hour = 23
components.minute = 59
components.second = 59
let endDate = calendar.date(from: components)
return NSPredicate(format: "YOUR_DATE_FIELD >= %@ AND YOUR_DATE_FIELD =< %@", argumentArray: [startDate!, endDate!])
}
私は最近、この同じ問題を解決しようとしてしばらく時間を費やし、開始日と終了日を準備するための代替案のリストに以下を追加しました(iOS 8以降の更新方法を含む)...
NSDate *dateDay = nil;
NSDate *dateDayStart = nil;
NSDate *dateDayNext = nil;
dateDay = <<USER_INPUT>>;
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];
...そしてその NSPredicate
コアデータの場合 NSFetchRequest
(他の回答にすでに上記のように)...
[NSPredicate predicateWithFormat:@"(dateAttribute >= %@) AND (dateAttribute < %@)", dateDayStart, dateDayNext]]
私にとってこれは機能しています。
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *components = [calendar components:(NSYearCalendarUnit | NSMonthCalendarUnit ) fromDate:[NSDate date]];
//create a date with these components
NSDate *startDate = [calendar dateFromComponents:components];
[components setMonth:0];
[components setDay:0]; //reset the other components
[components setYear:0]; //reset the other components
NSDate *endDate = [calendar dateByAddingComponents:components toDate:startDate options:0];
startDate = [NSDate date];
endDate = [startDate dateByAddingTimeInterval:-(7 * 24 * 60 * 60)];//change here
NSString *startTimeStamp = [[NSNumber numberWithInt:floor([endDate timeIntervalSince1970])] stringValue];
NSString *endTimeStamp = [[NSNumber numberWithInt:floor([startDate timeIntervalSince1970])] stringValue];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"((paidDate1 >= %@) AND (paidDate1 < %@))",startTimeStamp,endTimeStamp];
NSLog(@"predicate is %@",predicate);
totalArr = [completeArray filteredArrayUsingPredicate:predicate];
[self filterAndPopulateDataBasedonIndex];
[self.tableviewObj reloadData];
NSLog(@"result is %@",totalArr);
現在の日付から7日前に配列をフィルタリングしました。私は現在の日付から1週間のデータを取得しているということです。これは機能するはずです。
注:Milli秒で1000秒で来る日付を変換し、後に比較しています。明確さが必要な場合はお知らせください。