2 NSDateComponents - это та же неделя?

У меня есть функция с возвращаемым значением BOOL и двумя входными параметрами (NSDateComponents *). Моя проблема в том, что у меня есть два значения NSDateComponents, и я хочу знать, попадают ли эти две даты в одну и ту же календарную неделю. Я пробовал самые простые решения для решения проблемы, моя идея была следующей:

- (BOOL)isFunctionName:(NSDateComponents *)comp1 andParam:(NSDateComponents *)comp2 { return (([comp1 week] == [comp2 week]) && ([comp1 year] == [comp2 year])); }

но это неправильно. каким образом я могу это решить?


отредактировано

поэтому у меня есть функция, которая делает компоненты даты из дат.

-(NSDateComponents *)dateToDateComponents:(NSDate *)date { unsigned unitFlags = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit; NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; NSDateComponents *dateComponents = [gregorian components:unitFlags fromDate:date]; [gregorian release]; return dateComponents; }

и я называю это так:

if ([self isFunctionName: [self dateToDateComponents:startDate] and Param:[self dateToDateComponents:currentTripDate]]){ }

и во время моего теста он возвращает ДА ​​все мои даты (например, 2010.07.21 - 2010.08.18)


person Victor    schedule 25.08.2010    source источник


Ответы (3)


Ссылка на класс NSDateComponent гласит:

Важно! Объект NSDateComponents сам по себе не имеет смысла; вам нужно знать, по какому календарю он интерпретируется, и вам нужно знать, являются ли значения абсолютными значениями единиц или количеством единиц.

А как насчет сравнения NSDates?

- (BOOL) weekIsEqual:(NSDate *)date and:(NSDate *)otherDate {
  NSCalendar *gregorian = [[[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar] autorelease];

  NSDateComponents *dateComponents      = [gregorian components:NSWeekdayCalendarUnit | NSYearCalendarUnit fromDate:date];
  NSDateComponents *otherDateComponents = [gregorian components:NSWeekdayCalendarUnit | NSYearCalendarUnit fromDate:otherDate];

  return [dateComponents week] == [otherDateComponents week] && [dateComponents year] == [otherDateComponents year];
}

редактировать: в этой строке:

 unsigned unitFlags = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit;

Вы не проходите NSWeekCalendarUnit, поэтому [dateComponent week] возвращает NSUndefinedDateComponent

изменить

Конечно, это должно быть NSWeekCalendarUnit

person Robert    schedule 25.08.2010
comment
я вызываю свои функции следующим образом: - person Victor; 25.08.2010
comment
есть функция dateToDateComponents, которая делает DateComponents из дат без знака unitFlags = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit; NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; NSDateComponents *dateComponents = [григорианские компоненты:unitFlags fromDate:date]; [григорианский релиз]; компоненты даты возврата; - person Victor; 25.08.2010
comment
так что это было два свидания, и я хочу справиться с ними. - person Victor; 25.08.2010
comment
хорошо, я вижу, добавил NSWeekdayCalendarUnit, и после этого я получил EXC_BAD_ACCES после NSLog(@comp1 неделя: %@ [comp1 неделя]): S - person Victor; 26.08.2010
comment
[comp1 неделя] возвращает NSInteger, если вы используете, например. NSLog(@%@, 34), 34 будет разыменован, как если бы это был указатель, который вызовет плохой сигнал доступа. Попробуйте NSLog(@comp1 неделя: %i, [comp1 неделя]); вместо - person Robert; 26.08.2010
comment
тем временем я пробовал много решений, %i была хорошей идеей, но значение недели компа равно 2147483647 (верхний предел NSInteger) по-прежнему не дает результата:/ - person Victor; 26.08.2010
comment
Вы должны передать NSWeekCalendarUnit, чтобы получить компонент даты, соответствующий неделе. - person Robert; 26.08.2010
comment
Это не работает, когда неделя пересекает два года. Например, 31.12.2012 и 01.01.2013. Метод Роберта вернет НЕТ, тогда как в приложениях ожидается ответ ДА. — Джозеф Лин 1 минуту назад редактировать - person Joseph Lin; 08.01.2013
comment
Многие вещи сейчас устарели, например NSGregorianCalendar. - person pragmus; 23.01.2017

Это вдохновлено ответом Роберта. Я немного изменил его, чтобы решить проблему, когда неделя пересекает два года, например. 31.12.2012 и 01.01.2013.

- (BOOL)isOnSameWeekAsDate:(NSDate*)otherDate
{
    NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
    unsigned unitFlags = NSCalendarUnitYearForWeekOfYear | NSCalendarUnitWeekOfYear;

    NSDateComponents *components = [calendar components:unitFlags fromDate:self];
    NSDateComponents *otherComponents = [calendar components:unitFlags fromDate:otherDate];

    return ( [components yearForWeekOfYear] == [otherComponents yearForWeekOfYear] && [components weekOfYear] == [otherComponents weekOfYear] );
}
person Joseph Lin    schedule 07.01.2013
comment
Я думаю, что это ответ. Я не нашел его в другом месте в Интернете. Однако константы, которые вы используете, устарели. - person Colas; 08.10.2015
comment
Ваш ответ больше не полезен в iOS8... см. nshipster.com/nscalendar-additions - person Colas; 08.10.2015
comment
Сохраните его для iOS7 и ранее... Я пытался найти решение для isOnPreviousWeek... Можете ли вы сделать это легко? - person Colas; 09.10.2015

Начиная с iOS8 это стало намного проще:

-(BOOL)isDate:(NSDate *)date1 onSameWeekAs:(NSDate *)date2
{
    return [[NSCalendar currentCalendar] isDate:date1
                                    equalToDate:date2
                              toUnitGranularity:NSCalendarUnitWeekOfYear];
}

Из документация:

возвращает YES, если обе даты имеют одинаковый компонент даты для всех единиц, больших или равных заданной единице, в противном случае NO.

person yonilevy    schedule 12.02.2016