NSCalendar primeiro dia da semana

Alguém sabe se existe uma maneira de definir o primeiro dia da semana em um NSCalendar, ou se há um calendar que já tenha segunda-feira como o primeiro dia da semana, em vez de domingo. No momento, estou trabalhando em um aplicativo baseado em cerca de uma semana de trabalho e ele precisa começar na segunda-feira, não no domingo. Eu provavelmente posso fazer algum trabalho para contornar isso, mas haverá muitos casos importantes. Eu prefiro que a plataforma faça isso por mim.

desde já, obrigado

Aqui está um pouco do código que estou usando. é sábado agora, então o que eu espero é que o dia da semana seja 6, em vez de 7. Isso significaria que o domingo seria 7 em vez de rolar para 0

NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; [gregorian setFirstWeekday:0]; unsigned unitFlags = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit | NSWeekCalendarUnit | NSWeekdayCalendarUnit; NSDateComponents *todaysDate = [gregorian components:unitFlags fromDate:[NSDate date]]; int dayOfWeek = todaysDate.weekday; 

Edit: Isso não verifica o caso de borda onde o início da semana começa no mês anterior. Alguns códigos atualizados para cobrir isso: https://stackoverflow.com/a/14688780/308315


Caso alguém ainda esteja prestando atenção a isso, você precisa usar

 ordinalityOfUnit:inUnit:forDate: 

e defina firstWeekday para 2. (1 == domingo e 7 = = sábado)

Aqui está o código:

 NSCalendar *gregorian = [[[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar] autorelease]; [gregorian setFirstWeekday:2]; // Sunday == 1, Saturday == 7 NSUInteger adjustedWeekdayOrdinal = [gregorian ordinalityOfUnit:NSWeekdayCalendarUnit inUnit:NSWeekCalendarUnit forDate:[NSDate date]]; NSLog(@"Adjusted weekday ordinal: %d", adjustedWeekdayOrdinal); 

Lembre-se, os ordinais para os dias da semana começam em 1 para o primeiro dia da semana, não para zero.

Link de documentação .

Este código constrói uma data definida para segunda-feira da semana atual:

 NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; NSDate *today = [NSDate date]; NSDate *beginningOfWeek = nil; BOOL ok = [gregorian rangeOfUnit:NSWeekCalendarUnit startDate:&beginningOfWeek interval:NULL forDate: today]; 

setFirstWeekday: no object NSCalendar. Define o índice do primeiro dia da semana para o receptor.

 - (void)setFirstWeekday:(NSUInteger)weekday 

Deve fazer o truque.

Na minha opinião, essas configurações devem ser dinâmicas de acordo com a localidade do usuário. Portanto, deve-se usar:

 NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; [gregorian setLocale:[NSLocale currentLocale]]; 

Isso fará com que o calendar defina o primeiro dia da semana de acordo com a localidade do usuário automaticamente. A menos que você esteja desenvolvendo seu aplicativo para uma finalidade específica / localidade do usuário (ou prefira permitir que o usuário escolha este dia).

Eu tive problemas com muitas das respostas aqui. . Talvez tenha sido apenas eu. .

Aqui está uma resposta que funciona para mim:

 - (NSDate*)firstDayOfWeek { NSCalendar* cal = [[NSCalendar currentCalendar] copy]; [cal setFirstWeekday:2]; //Override locale to make week start on Monday NSDate* startOfTheWeek; NSTimeInterval interval; [cal rangeOfUnit:NSWeekCalendarUnit startDate:&startOfTheWeek interval:&interval forDate:self]; return startOfTheWeek; } - (NSDate*)lastDayOfWeek { NSCalendar* cal = [[NSCalendar currentCalendar] copy]; [cal setFirstWeekday:2]; //Override locale to make week start on Monday NSDate* startOfTheWeek; NSTimeInterval interval; [cal rangeOfUnit:NSWeekCalendarUnit startDate:&startOfTheWeek interval:&interval forDate:self]; return [startOfTheWeek dateByAddingTimeInterval:interval - 1]; } 

Atualizar:

Como apontado (em outros lugares ) por @vikingosegundo, em geral é melhor deixar o local determinar qual dia é o início da semana, no entanto, neste caso, o OP estava pedindo que o início da semana ocorresse na segunda-feira, por isso copiamos o calendar do sistema e substitua o firstWeekDay.

O problema com a resposta de Kris é o caso extremo em que o começo da semana começa no mês anterior. Aqui está um código mais fácil e também verifica o caso da borda:

 // Finds the date for the first day of the week - (NSDate *)getFirstDayOfTheWeekFromDate:(NSDate *)givenDate { NSCalendar *calendar = [NSCalendar currentCalendar]; // Edge case where beginning of week starts in the prior month NSDateComponents *edgeCase = [[NSDateComponents alloc] init]; [edgeCase setMonth:2]; [edgeCase setDay:1]; [edgeCase setYear:2013]; NSDate *edgeCaseDate = [calendar dateFromComponents:edgeCase]; NSDateComponents *components = [calendar components:NSYearCalendarUnit|NSMonthCalendarUnit|NSWeekCalendarUnit|NSWeekdayCalendarUnit fromDate:edgeCaseDate]; [components setWeekday:1]; // 1 == Sunday, 7 == Saturday [components setWeek:[components week]]; NSLog(@"Edge case date is %@ and beginning of that week is %@", edgeCaseDate , [calendar dateFromComponents:components]); // Find Sunday for the given date components = [calendar components:NSYearCalendarUnit|NSMonthCalendarUnit|NSWeekCalendarUnit|NSWeekdayCalendarUnit fromDate:givenDate]; [components setWeekday:1]; // 1 == Sunday, 7 == Saturday [components setWeek:[components week]]; NSLog(@"Original date is %@ and beginning of week is %@", givenDate , [calendar dateFromComponents:components]); return [calendar dateFromComponents:components]; } 

Eu fiz assim.

 NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; NSDate *today = [NSDate date]; NSDateComponents *compForWeekday = [gregorian components:(NSWeekdayCalendarUnit) fromDate:today]; NSInteger weekDayAsNumber = [compForWeekday weekday]; // The week day as number but with sunday starting as 1 weekDayAsNumber = ((weekDayAsNumber + 5) % 7) + 1; // Transforming so that monday = 1 and sunday = 7 

Eu vejo mal entendido nas outras mensagens. O primeiro dia da semana, o que for, tem o número 1 e não 0. Por padrão, domingo = 1, como na “Introdução ao Guia de Programação de Data e Hora do cocoa: Cálculos do Calendárico”:

“O valor do dia da semana para domingo no calendar gregoriano é 1”

Para a segunda-feira como um primeiro dia de trabalho, o único remédio que tenho é a condição de força bruta para corrigir o cálculo

 NSCalendar *cal=[[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; NSDateComponents *comps = [cal components:NSWeekdayCalendarUnit fromDate:[NSDate date]]; // set to 7 if it's Sunday otherwise decrease weekday number NSInteger weekday=[comps weekday]==1?7:[comps weekday]-1; 

Abaixo também cobre o caso de borda,

 - (NSDate *)getFirstDayOfTheWeekFromDate:(NSDate *)givenDate { NSCalendar *calendar = [NSCalendar currentCalendar]; NSDateComponents *components = [calendar components:NSYearCalendarUnit|NSMonthCalendarUnit|NSWeekCalendarUnit|NSWeekdayCalendarUnit fromDate:givenDate]; [components setWeekday:2]; // 1 == Sunday, 7 == Saturday if([[calendar dateFromComponents:components] compare: curDate] == NSOrderedDescending) // if start is later in time than end { [components setWeek:[components week]-1]; } return [calendar dateFromComponents:components]; } 

Tente isto:

 NSCalendar *yourCal = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar] [yourCal setFirstWeekday:0]; 

… Existe um calendar que já tem segunda-feira como o primeiro dia da semana, em vez de domingo.

Algum dia haverá.

Iv descobriu o caminho para exibir qualquer nome de dia da semana usando nscalender..using o código a seguir .. Basta abrir o console da barra de menu xcode para ver os resultados.Copy Cole o seguinte código em seu método viewDidLoad para obter o primeiro dia da semana

 NSDate *today = [NSDate date]; NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init]; [dateFormat setDateFormat:@"MM/dd/yyyy :EEEE"]; NSString *dateString = [dateFormat stringFromDate:today]; NSLog(@"date: %@", dateString); [dateFormat release]; NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; NSDateComponents *components = [gregorian components:NSWeekdayCalendarUnit | NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit fromDate:today]; [components setDay:([components day]-([components weekday]-1))]; NSDate *beginningOfWeek = [gregorian dateFromComponents:components]; NSDateFormatter *dateFormat_first = [[NSDateFormatter alloc] init]; [dateFormat_first setDateFormat:@"MM/dd/yyyy :EEEE"]; NSString *dateString_first = [dateFormat_first stringFromDate:beginningOfWeek]; NSLog(@"First_date: %@", dateString_first); 

A saída será:

  date: 02/11/2010 :Thursday First_date: 02/07/2010 :Sunday 

desde que eu tinha executado este programa em 2/11/2010 vc vai obter o resultado desejado dependendo da data atual.

Da mesma forma, se você deseja obter o primeiro dia útil da semana, ou seja, a data de segunda-feira, modifique o código um pouco:

MUDANÇA: [components setDay:([components day]-([components weekday]-1))];

TO [components setDay:([components day]-([components weekday]-2))];

para obter as segundas-feiras data para essa semana ..

Da mesma forma u pode tentar encontrar a data de qualquer um dos sete dias úteis, alterando o inteiro -1, -2 e assim por diante …

Espero que sua pergunta seja respondida ..

Obrigado, Bonson Dias

Minha maneira simples de fazer isso é obter segunda-feira = 0, domingo = 6:

  NSDateComponents *dateComponents = [[NSCalendar currentCalendar] components:NSWeekdayCalendarUnit fromDate:[NSDate date]]; NSInteger dayNumStartingFromMonday = ([dateComponents weekday] - 2 + 7) % 7; //normal: Sunday is 1, Monday is 2 

O calendar ISO 8601 parece ter seu primeiro dia da semana definido como segunda-feira por padrão.

Usando o Calendário nextWeekend (iOS 10 ou posterior) e ordinality (thanks @ kris-markel). Eu comecei segunda-feira como primeiro da semana para o calendar en_US.

Aqui está um exemplo disso com fallback para firstWeekday:

 extension Calendar { var firstWorkWeekday: Int { guard #available(iOS 10.0, *) else{ return self.firstWeekday } guard let endOfWeekend = self.nextWeekend(startingAfter: Date())?.end else { return self.firstWeekday } return self.ordinality(of: .weekday, in: .weekOfYear, for: endOfWeekend) ?? self.firstWeekday } } 

Você pode apenas alterar a primeira .firstWeekday do calendar.

 NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian]; calendar.firstWeekday = 2; 

Em seguida, use rangeOfUnit:startDate:interval:forDate: para obter o primeiro dia

 NSDate *startOfWeek; [calendar rangeOfUnit:NSCalendarUnitWeekOfYear startDate:&startOfWeek interval:nil forDate:[NSdate date]];