NSPredicate- For finding events that occur between a certain date range

前端 未结 4 1816
情深已故
情深已故 2021-01-03 10:42

This is a little more complicated then just

NSPredicate *predicate = [NSPredicate predicateWithFormat:@\"startDate >= %@ AND endDate <= %@\", startDay,         


        
4条回答
  •  误落风尘
    2021-01-03 11:11

    Here is a method to build a predicate to retrieve non recurring events occurring on a given day (recurring events require additional processing):

    - (NSPredicate *) predicateToRetrieveEventsForDate:(NSDate *)aDate {
    
        // start by retrieving day, weekday, month and year components for the given day
        NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
        NSDateComponents *todayComponents = [gregorian components:(NSDayCalendarUnit | NSMonthCalendarUnit | NSYearCalendarUnit) fromDate:aDate];
        NSInteger theDay = [todayComponents day];
        NSInteger theMonth = [todayComponents month];
        NSInteger theYear = [todayComponents year];
    
        // now build a NSDate object for the input date using these components
        NSDateComponents *components = [[NSDateComponents alloc] init];
        [components setDay:theDay]; 
        [components setMonth:theMonth]; 
        [components setYear:theYear];
        NSDate *thisDate = [gregorian dateFromComponents:components];
        [components release];
    
        // build a NSDate object for aDate next day
        NSDateComponents *offsetComponents = [[NSDateComponents alloc] init];
        [offsetComponents setDay:1];
        NSDate *nextDate = [gregorian dateByAddingComponents:offsetComponents toDate:thisDate options:0];
        [offsetComponents release];
    
        [gregorian release];
    
    
        // build the predicate 
        NSPredicate *predicate = [NSPredicate predicateWithFormat: @"startDate < %@ && endDate > %@", nextDate, thisDate];
    
            return predicate;
    
    }
    

    The predicate is almost equal to the one proposed by @Tony, except it does not check for equality. Here is why. Suppose you have an event starting on December 8 23:00 and ending at December 9 00:00. If you check for events whose ending date is >= rather than > of the given day, your app will report the event in both December 8 and 9, which is clearly wrong. Try adding such an event to both iCal and Google Calendar, and you will see that the event only appears on December 8. In practice, you should not assume that a given day ends at 23:59:59 (even though this is of course true): you need to treat midnight as the last second of a given day (with regard to the end of an event). Also, note that this does not prevent events starting at midnight.

提交回复
热议问题