nombre de semaines calendaires pour l'année (définition ISO 8601)
-
13-12-2019 - |
Question
comment puis-je calculer le nombre de semaines calendaires en objectif-C pour une année donnée.
J'ai essayé:
[calendar rangeOfUnit:NSWeekOfYearCalendarUnit inUnit: NSYearCalendarUnit forDate: [NSDate date]].length
mais il renvoie 54.
Merci
La solution
Vous utilisez NSWeekOfYearCalendarUnit
, vous devez donc utiliser l'unité correspondante plus grande qui est 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
Enfin, notons que les deux NSWeekOfYearCalendarUnit
et NSYearForWeekOfYearCalendarUnit
sont iOS 5.0 et OS X 10.7 uniquement.
Modifier
Comme l'a noté @lnafziger, si vous utilisez une date qui se situe dans une semaine civile de l'année précédente ou de l'année suivante, comme le 1/1/2016, cela calculera le nombre de semaines de cette année (2015 dans l'exemple), et pas l'année réelle de la date (2016 dans l'exemple).Si ce n'est pas ce que vous souhaitez, vous pouvez modifier la date comme suit :
NSDateComponents *components = [calendar components:NSYearCalendarUnit fromDate:date];
components.month = 3;
date = [calendar dateFromComponents:components];
Autres conseils
Après une quantité importante de tests, voici une fonction qui le retournera pendant toute année:
- (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;
}
Fondamentalement, selon la spécification, le nombre total de semaines est identique au nombre total de jeudi de l'année, ce qui est ce que cela calcule.
Je l'ai testé pour l'ensemble du cycle de 400 ans (à partir de l'année 0 et 2000) et tous les cas correspondent à la spécification.