Fetching events in specified time interval using Event Kit does not work as expected
I am using Event Kit on iOS 4.3.1 to retrieve all of the events in a specified time interval. However, I am experiencing the following problems.
1) using as start date [NSDate distantPast] and as end date [NSDate distantFuture] does not return any event.
EKEventStore *store = [[EKEventStore alloc] init];
// Create the predicate.
NSPredicate *eventPredicate = [store predicateForEventsWithStartDate:[NSDate distantPast] endDate:[NSDate distantFuture] calendars:store.calendars];
// Fetch all events that match the predicate.
NSArray *events = [[store eventsMatchingPredicate:eventPredicate] retain];
2) Setting the start date to 10 years ago and the end date to 10 year from now only fetches events up to 2005. Nothing else is returned.
EKEventStore *store = [[EKEventStore alloc] init];
CFGregorianDate gregorianStartDate, gregorianEndDate;
CFGregorianUnits startUnits = {-10, 0, 0, 0, 0, 0};
CFGregorianUnits endUnits = {10, 0, 0, 0, 0, 0};
CFTimeZoneRef timeZone = CFTimeZoneCopySystem();
gregorianStartDate = CFAbsoluteTimeGetGregorianDate(
CFAbsoluteTimeAddGregorianUnits(CFAbsoluteTimeGetCurrent(),
timeZone,
startUnits),
timeZone);
gregorianStartDate.hour = 0;
gregorianStartDate.minute = 0;
gregorianStartDate.second = 0;
gregorianEndDate = CFAbsoluteTimeGetGregorianDate(
CFAbsoluteTimeAddGregorianUnits(CFAbsoluteTimeGetCurrent(),
timeZone,
endUnits),
timeZone);
gregorianEndDate.hour = 0;
gregorianEndDate.minute = 0;
gregorianEndDate.second = 0;
NSDate* startDate =
[NSDate dateWithTimeIntervalSinceReferenceDate:CFGregorianDateGetAbsoluteTime(gregorianStartDate, timeZone)];
NSDate* endDate =
[NSDate dateWithTimeIntervalSinceReferenceDate:CFGregorianDateGetAbsoluteTime(gregorianEndDate, timeZone)];
CFRelease(timeZone);
// Create the predicate.
NSPredicate *eventPredicate = [store predicateForEventsWithStartDate:startDate endDate:endDate calendars:store.c开发者_开发知识库alendars];
// Fetch all events that match the predicate.
NSArray *events = [[store eventsMatchingPredicate:eventPredicate] retain];
So, I was wondering if the snippet of code posted is correct or if I am doing something wrong. Ideally I would like to use [NSDate distantPast] and [NSDate distantFuture] to retrieve in a single call all of the events in all of the calendars. Is this actually possible? Also, since even the second example does not work (at least for me), what is the proper way to retrieve all of the events? Do I need multiple calls with a narrow time interval? If yes, what is the largest time interval once can use to retrieve the events? Thank you in advance.
AFAIK, this is correct. It doesn't look like the mistake is in this part of the code. I punched your second snippet into a scratch app.
CFGregorianDate gregorianStartDate, gregorianEndDate;
CFGregorianUnits startUnits = {-10, 0, 0, 0, 0, 0};
CFGregorianUnits endUnits = {10, 0, 0, 0, 0, 0};
CFTimeZoneRef timeZone = CFTimeZoneCopySystem();
gregorianStartDate = CFAbsoluteTimeGetGregorianDate(
CFAbsoluteTimeAddGregorianUnits(CFAbsoluteTimeGetCurrent(),
timeZone,
startUnits),
timeZone);
gregorianStartDate.hour = 0;
gregorianStartDate.minute = 0;
gregorianStartDate.second = 0;
gregorianEndDate = CFAbsoluteTimeGetGregorianDate(
CFAbsoluteTimeAddGregorianUnits(CFAbsoluteTimeGetCurrent(),
timeZone,
endUnits),
timeZone);
gregorianEndDate.hour = 0;
gregorianEndDate.minute = 0;
gregorianEndDate.second = 0;
NSDate* startDate =
[NSDate dateWithTimeIntervalSinceReferenceDate:CFGregorianDateGetAbsoluteTime(gregorianStartDate, timeZone)];
NSDate* endDate =
[NSDate dateWithTimeIntervalSinceReferenceDate:CFGregorianDateGetAbsoluteTime(gregorianEndDate, timeZone)];
NSDateFormatter *dateFormatter = [[[NSDateFormatter alloc] init]autorelease];
[dateFormatter setTimeStyle:NSDateFormatterNoStyle];
[dateFormatter setDateStyle:NSDateFormatterMediumStyle];
NSLocale *usLocale = [[[NSLocale alloc] initWithLocaleIdentifier:@"en_US"]autorelease];
[dateFormatter setLocale:usLocale];
NSDate *today = [[[NSDate alloc] init] autorelease];
NSLog(@"Date for locale %@: %@",[[dateFormatter locale] localeIdentifier], [dateFormatter stringFromDate:today]);
NSLog(@"Date for locale %@: %@",[[dateFormatter locale] localeIdentifier], [dateFormatter stringFromDate:startDate]);
NSLog(@"Date for locale %@: %@",[[dateFormatter locale] localeIdentifier], [dateFormatter stringFromDate:endDate]);
CFRelease(timeZone);
I got the following output:
2011-11-23 13:31:40.244 Testapp[15440:207] Date for locale en_US: Nov 23, 2011
2011-11-23 13:31:41.195 Testapp[15440:207] Date for locale en_US: Nov 23, 2001
2011-11-23 13:31:42.063 Testapp[15440:207] Date for locale en_US: Nov 23, 2021
Good Luck.
BTW, I would use NSDateComponent
to get 10 years into the future and 10 years in the past.
Add this to the above code,
NSDateComponents *yearForPredicate = [[[NSDateComponents alloc] init]autorelease];
NSCalendar *gregorian = [[[NSCalendar alloc] initWithCalendar:NSGgregorianCalendar]autorelease];
[yearForPredicate setYear:10];
NSDate *distantFuture = [gregorian dateByAddingComponents:yearForPredicate toDate:today options:0];
[yearForPredicate setYear:-10]
NSDate *distantPast = [gregorian dateByAddingComponents:yearForPredicate toDate:today options:0];
精彩评论