número de semanas do calendário por ano (definição ISO 8601)
-
13-12-2019 - |
Pergunta
como posso calcular o número de semanas do calendário no objetivo-C para um determinado ano.
Tentei:
[calendar rangeOfUnit:NSWeekOfYearCalendarUnit inUnit: NSYearCalendarUnit forDate: [NSDate date]].length
mas retorna 54.
Obrigado
Solução
Você está usando NSWeekOfYearCalendarUnit
, então você deve usar a unidade maior correspondente que é NSYearForWeekOfYearCalendarUnit
.
NSCalendar *calendar = [NSCalendar currentCalendar];
calendar.firstWeekday = 2;
calendar.minimumDaysInFirstWeek = 4;
int n = [calendar rangeOfUnit:NSWeekOfYearCalendarUnit inUnit:NSYearForWeekOfYearCalendarUnit forDate: [NSDate date]].length;
NSLog(@"%d", n); // 52
Por fim, observe que ambos NSWeekOfYearCalendarUnit
e NSYearForWeekOfYearCalendarUnit
são apenas iOS 5.0 e OS X 10.7.
Editar
Conforme observado por @lnafziger, se você usar uma data que esteja em uma semana do calendário do ano anterior ou do próximo ano, como 01/01/2016, isso calculará o número de semanas naquele ano (2015 no exemplo) e não o ano real da data (2016 no exemplo).Se não for isso que você deseja, você pode alterar a data da seguinte forma:
NSDateComponents *components = [calendar components:NSYearCalendarUnit fromDate:date];
components.month = 3;
date = [calendar dateFromComponents:components];
Outras dicas
Depois de uma quantidade significativa de testes, aqui está uma função que irá retorná-la para qualquer ano:
- (NSUInteger)iso8601WeeksForYear:(NSUInteger)year {
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *firstThursdayOfYearComponents = [[NSDateComponents alloc] init];
[firstThursdayOfYearComponents setWeekday:5]; // Thursday
[firstThursdayOfYearComponents setWeekdayOrdinal:1]; // The first Thursday of the month
[firstThursdayOfYearComponents setMonth:1]; // January
[firstThursdayOfYearComponents setYear:year];
NSDate *firstThursday = [calendar dateFromComponents:firstThursdayOfYearComponents];
NSDateComponents *lastDayOfYearComponents = [[NSDateComponents alloc] init];
[lastDayOfYearComponents setDay:31];
[lastDayOfYearComponents setMonth:12];
[lastDayOfYearComponents setYear:year];
NSDate *lastDayOfYear = [calendar dateFromComponents:lastDayOfYearComponents];
NSDateComponents *result = [calendar components:NSWeekCalendarUnit fromDate:firstThursday toDate:lastDayOfYear options:0];
return result.week + 1;
}
Basicamente, de acordo com as especificações, o número total de semanas é igual ao número total de quintas-feiras do ano, que é o que calcula.
Eu testei durante todo o ciclo de 400 anos (começando no ano 0 e no ano 2000) e todos os casos correspondem às especificações.