2013-07-24 5 views

ответ

2

Несколько иной метод для Matthias's, хотя я не вижу никакого хорошего способа сделать это с помощью NSPredicate либо, так как здесь требуется арифметика даты.

Это создает компоненты даты с каждой даты изначально и рассчитывает их с использованием NSCountedSet. (Вы можете быть в состоянии использовать предикат на множестве подсчитывались.) Затем создается другой NSDateComponents объект, описывающий месяц и год вы заинтересованы, и просто запросить набор с помощью countForObject:

NSArray * dates = @[/* Your dates here */]; 

NSCalendar * cal = [NSCalendar currentCalendar]; 

/* Convert the dates into date components objects for month and year. */ 
NSMutableArray * months = [NSMutableArray array]; 
for(NSDate * date in dates){ 

    NSDateComponents * month = [cal components:(NSMonthCalendarUnit|NSYearCalendarUnit) 
             fromDate:date]; 
    [months addObject:month]; 
} 

/* Count the unique components. */ 
NSCountedSet * monthsCounts = [NSCountedSet setWithArray:months]; 

/* Use a predicate here on the set? */ 

/* A components object for month arithmetic. */ 
NSDateComponents * monthDelta = [NSDateComponents new]; 

/* Get month names for the current locale. */ 
NSDateFormatter * formatter = [NSDateFormatter new]; 
NSArray * monthNames = [formatter monthSymbols]; 

for(NSInteger i = 0; i > -NUM_MONTHS; i--){ 

    /* Couting backwards from the current month, get a date components 
    * object for each month and year. 
    */ 
    [monthDelta setMonth:i]; 
    NSDateComponents * currMonth; 
    currMonth = [cal components:(NSMonthCalendarUnit|NSYearCalendarUnit) 
         fromDate:[cal dateByAddingComponents:monthDelta 
                toDate:[NSDate date] 
                options:0]]; 
    /* Get the count from the counted set and display. */ 
    NSUInteger count = [monthsCounts countForObject:currMonth]; 
    NSLog(@"%lu dates in %@", count, 
      [monthNames objectAtIndex:[currMonth month] - 1]); 
} 
1

Вы должны проверить даты в своем массиве 6 раз.

Во-первых: соответствие всем датам 1 июля и не позднее 1 августа.
Во-вторых: сопоставьте все даты 1 или 1 июня и до 1 июля.
В-третьих: сопоставьте все даты или после 1 мая и до 1 июня.
и т. Д.

В цикле вы создаете две даты. Первая дата - начало месяца в полночь. Вторая дата - ровно 1 месяц (!). Затем вы отфильтровываете все даты из массива, который включен или после первой и перед второй датой. В следующей итерации цикла вы делаете startDate на месяц раньше, чем предыдущий startDate.

Множество расчетных дат, но с помощью NSDateComponents это не имеет большого значения.

Поскольку я не знаю, как использовать NSPredicate с NSDates в массиве я использовал другой метод, но это в основном, как это работает:

NSDateComponents *oneMonthOffset = [[NSDateComponents alloc] init]; 
oneMonthOffset.month = 1; 

NSDateComponents *thisMonth = [calendar components:NSYearCalendarUnit|NSMonthCalendarUnit fromDate:[NSDate date]]; 
thisMonth.day = 1; 
NSDate *startOfCurrentMonth = [calendar dateFromComponents:thisMonth]; 

for (NSInteger offset = 0; offset > -5; offset--) { 
    NSDateComponents *startDateOffset = [[NSDateComponents alloc] init]; 
    startDateOffset.month = offset; 
    NSDate *startDate = [calendar dateByAddingComponents:startDateOffset toDate:startOfCurrentMonth options:0]; 
    NSDate *endDate = [calendar dateByAddingComponents:oneMonthOffset toDate:startDate options:0]; 
    NSIndexSet *matchingIndexes = [array indexesOfObjectsPassingTest:^BOOL(NSDate *date, NSUInteger idx, BOOL *stop) { 
     if ([date compare:startDate] != NSOrderedAscending && [date compare:endDate] == NSOrderedAscending) { 
      // date is not before startDate (i.e. is on startDate or later than startDate) and date is before endDate 
      return YES; 
     } 
     return NO; 
    }]; 
    NSLog(@"%d dates after %@ and before %@", [matchingIndexes count], [startDate descriptionWithLocale:[NSLocale currentLocale]], [endDate descriptionWithLocale:[NSLocale currentLocale]]); 
} 

Если массив дат очень большой вы могли бы хотите сначала отсортировать его и только просмотреть соответствующий диапазон. Этот код в настоящее время проверяет все NSDates в массиве.

Смежные вопросы