Нахождение понедельника, предшествующего текущему дню на iOS - PullRequest
2 голосов
/ 03 февраля 2011

У меня есть ситуация, когда мне нужен понедельник перед определенной датой (определенная дата здесь localtournament.entryDeadline) Я попробовал ниже, но он возвращает мне ту же дату. Я нашел несколько похожих вопросов, но ни один из них не может сделать это на iOS. Кажется, это должно быть легко, мне действительно нравится структура дат Какао, но я в данный момент нахожусь в тупике.

Что я делаю не так? Результат (который всегда должен быть понедельником и не должен) находится в localTournament.entryOpen.

NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *comps = [calendar components:(NSYearCalendarUnit | NSWeekdayCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit) fromDate:localTournament.entryDeadline]; //1=sunday, 2=monday, etc

if(comps.weekday > 2) {
    //later in same week
    [comps setWeekday:2];
    [comps setHour:12];
    localTournament.entryOpen = [calendar dateFromComponents:comps];
} else if(comps.weekday == 1) {
    //sunday, go back a week
    [comps setWeek:-1];
    [comps setWeekday:2];
    [comps setHour:12];
    localTournament.entryOpen = [calendar dateByAddingComponents:comps toDate:localTournament.entryDeadline  options:0];

} else {
    //already monday, use previous week
    [comps setWeek:-1];
    [comps setHour:12];
    localTournament.entryOpen = [calendar dateByAddingComponents:comps toDate:localTournament.entryDeadline  options:0];
}

[calendar release];

Ответы [ 3 ]

1 голос
/ 04 февраля 2011

Решение (ниже) состояло в том, чтобы просто определить, сколько дней назад мне нужно было пойти и вычесть.

NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *comps = [calendar components:(NSYearCalendarUnit | NSWeekdayCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit) fromDate:localTournament.entryDeadline]; //1=sunday, 2=monday, etc

if(comps.weekday > 2) {
    //later in same week
    [comps setHour:12];
    localTournament.entryOpen = [calendar dateFromComponents:comps];

    NSDateComponents *sparseComps = [[[NSDateComponents alloc] init] autorelease];      
    [sparseComps setDay:0-(comps.weekday-2)];

    localTournament.entryOpen = [calendar dateByAddingComponents:sparseComps toDate:localTournament.entryOpen  options:0];
} else if(comps.weekday == 1) {
    //sunday, go back a week and add a day
    [comps setHour:12];
    localTournament.entryOpen = [calendar dateFromComponents:comps];

    NSDateComponents *sparseComps = [[[NSDateComponents alloc] init] autorelease];
    [sparseComps setWeek:-1];
    [sparseComps setWeekday:1];
    localTournament.entryOpen = [calendar dateByAddingComponents:sparseComps toDate:localTournament.entryOpen  options:0];
} else {
    //already monday, use previous week
    [comps setHour:12];
    localTournament.entryOpen = [calendar dateFromComponents:comps];

    NSDateComponents *sparseComps = [[[NSDateComponents alloc] init] autorelease];
    [sparseComps setWeek:-1];
    localTournament.entryOpen = [calendar dateByAddingComponents:sparseComps toDate:localTournament.entryOpen  options:0];
}

[calendar release];
1 голос
/ 03 февраля 2011

Если вы укажете оба компонента NSWeekdayCalendarUnit и NSDayCalendarUnit, методы NSCalendar предпочтут информацию о дне (которая не обновляется), а не информацию о дне недели (которая есть). Я бы либо полностью удалил NSDayCalendarUnit и заменил его на NSWeekCalendarUnit, либо обновил бы день вместо дня недели.

См. Документацию для dateFromComponents: для получения дополнительной информации.

0 голосов
/ 03 февраля 2013

Чтобы экстраполировать ответ Джастина, если вы хотите работать с неделями и днями недели, вы должны создать новый объект NSDateComponent, который содержит weekday и weekOfYear элементы INSTEAD из day и month компонентов.,Вам может понадобиться новый временный объект для этого.

Вот код из моего проекта, который находит в следующую пятницу, но это аналогичная идея: (calGergorian и dcNow - свойства моего класса, но должныне требует пояснений)

    _dcNextWeekReminderTime = [[NSDateComponents alloc] init];

    _dcNextWeekReminderTime.weekday = 6;
    _dcNextWeekReminderTime.weekOfYear = self.dcNow.weekOfYear;
    _dcNextWeekReminderTime.year = self.dcNow.year;
    _dcNextWeekReminderTime.calendar = self.calGregorian;

    //if the date we've just created is earlier than today...
    if ([[self.calGregorian dateFromComponents:_dcNextWeekReminderTime] timeIntervalSinceDate:[self.calGregorian dateFromComponents:self.dcNow]] < 0) {

        //...make it next week
        _dcNextWeekReminderTime.weekOfYear +=1;

    }

(простите за мой венгерский язык)

Чтобы решить вашу проблему, вы в основном изменили бы > на < в операторе if, иизмените +=1 на -=1 и число 6 (пятница) на 2 (понедельник).

Кроме того, если вы не работаете со старой версией iOS, week представляется устаревшим в пользуweekOfYear.

...