Как получить количество недель в месяц
Вот проблема, я ищу способ получить количество недель в месяц. Я уже нашел решение, которое, похоже, работает на ios 5, но оно не на io6 (число возвращаемое не то же самое, еще одно на ios 6).
- (int)weeksOfMonth:(int)month inYear:(int)year
{
NSCalendar *cCalendar = [NSCalendar currentCalendar];
NSDateComponents *components = [[NSDateComponents alloc] init];
[components setMonth:month];
[components setYear:year];
NSRange range = [cCalendar rangeOfUnit:NSDayCalendarUnit
inUnit:NSMonthCalendarUnit
forDate:[cCalendar dateFromComponents:components]];
cCalendar = [NSCalendar currentCalendar];
[cCalendar setMinimumDaysInFirstWeek:4];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init];
[dateFormatter setLocale: [[NSLocale alloc] initWithLocaleIdentifier:@"fr"]];
[dateFormatter setDateFormat:@"yyyy-MM-dd"];
NSMutableSet *weeks = [[NSMutableSet alloc] init ];
for(int i = 0; i < range.length; i++)
{
NSString *temp = [NSString stringWithFormat:@"%4d-%2d- %2d",year,month,range.location+i];
NSDate *date = [dateFormatter dateFromString:temp ];
int week = [[cCalendar components: NSWeekOfYearCalendarUnit fromDate:date] weekOfYear];
[weeks addObject:[NSNumber numberWithInt:week]];
}
return [weeks count];
}
Возвращаемое значение равно 6 на io6 и 5 на io5.
Есть ли у вас какие-либо идеи?
EDIT: Другое дело, мое устройство (ios5) находится на французском языке, а симулятор (ios6) находится на английском языке. Может быть, это может что-то изменить (например, в первый день недели?)?
Ответы
Ответ 1
Попробуй это:
NSDate *date = [NSDate date];//since you are forming date, put it here
NSCalendar *calender = [NSCalendar currentCalendar];
NSRange weekRange = [calender rangeOfUnit:NSWeekCalendarUnit inUnit:NSMonthCalendarUnit forDate:date];
NSInteger weeksCount=weekRange.length;
NSLog(@"%d",weeksCount);
Swift 4.0:
let date = Date()
let calendar = Calendar.current
let weekRange = calendar.range(of: .weekOfMonth,
in: .month,
for: date)
let weeksCount = weekRange.count ?? 0
print(weeksCount)
Или измените свой метод на:
- (NSInteger)weeksOfMonth:(int)month inYear:(int)year{
NSString *dateString=[NSString stringWithFormat:@"%4d/%d/1",year,month];
NSDateFormatter *dfMMddyyyy=[NSDateFormatter new];
[dfMMddyyyy setDateFormat:@"yyyy/MM/dd"];
NSDate *date=[dfMMddyyyy dateFromString:dateString];
NSCalendar *calender = [NSCalendar currentCalendar];
NSRange weekRange = [calender rangeOfUnit:NSWeekCalendarUnit inUnit:NSMonthCalendarUnit forDate:date];
NSInteger weeksCount=weekRange.length;
return weeksCount;
}
РЕДАКТИРОВАТЬ:
используйте это в методе выше
//NSCalendar *calender = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
[calender setFirstWeekday:2]; //sunday=1, monday=2 etc
Ответ 2
Проверьте этот подход.
-(NSArray*)getWeekDaysForDate {
int dayOfWeek = [self weekDay];
NSMutableArray *array = [NSMutableArray array];
NSDate *weekStartDate = [self offsetDay:1-dayOfWeek];
NSCalendar *calendar = [NSCalendar defaultCalendar];
NSInteger monthValue = [self month];
unsigned int weekNum = [[calendar components: NSWeekCalendarUnit
fromDate: weekStartDate] week];
NSDate * nextDate = weekStartDate, *curDate;
NSDateComponents *oneDay = [[NSDateComponents alloc] init];
[oneDay setDay:1];
unsigned int newWeekNum;
do {
curDate = nextDate;
nextDate = [calendar dateByAddingComponents:oneDay toDate: curDate
options:0];
newWeekNum = [[calendar components: NSWeekCalendarUnit fromDate:
nextDate] week];
int monthValueForNextDate = [[calendar components: NSMonthCalendarUnit fromDate:
nextDate] month];
if(monthValue == monthValueForNextDate)
[array addObject:nextDate]];
} while (newWeekNum == weekNum);
[array sortUsingSelector:@selector(compare:)];
return array;
}
-(int)month {
NSCalendar *gregorian = [NSCalendar defaultCalendar];
NSDateComponents *components = [gregorian components:NSMonthCalendarUnit fromDate:self];
return [components month];
}
-(int)weekDay {
NSCalendar *gregorian = [NSCalendar defaultCalendar];
NSDateComponents *components = [gregorian components:NSWeekdayCalendarUnit fromDate:self];
return [components weekday];
}
-(NSDate *)offsetDay:(int)numDays {
NSCalendar *gregorian = [NSCalendar defaultCalendar];
NSDateComponents *offsetComponents = [[NSDateComponents alloc] init];
[offsetComponents setDay:numDays];
return [gregorian dateByAddingComponents:offsetComponents
toDate:self options:0];
}
PS: NSCalendar defaultCalendar = [[NSCalendar alloc]initWithCalendarIdentifier:NSGregorianCalendar];
Добавив этот метод, категория NSDate
вернет рабочие дни любой даты, которая находится на той же неделе.
С наилучшими пожеланиями.