Получить последний вторник в месяц ios

Может получить последний рабочий день в месяц через NSDateComponents? Например: в последний понедельник месяца или последней пятницы в месяц. и т.д

Вот решение; испытал, и довольно прочный, я думаю. Мы будем пропускать NSCalendar через месяц, день за раз, и вытаскивать все соответствующие будние дни, как NSDates. Затем вы можете ответить на такие вопросы, как «Третья среда этого месяца»,

Я считаю, что комментарии ясны о том, что происходит, и почему. Если вам потребуются дополнительные разъяснения, я буду рад сделать это.

 //What weekday are we interested in? 1 = Sunday . . . 7 = Saturday NSInteger targetWeekday = 1; //Using this methodology, GMT timezone is important to set NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian]; calendar.timeZone = [NSTimeZone timeZoneWithAbbreviation:@"GMT"]; //set the components to the first of the current month NSDateComponents *startComponents = [calendar components:NSCalendarUnitMonth | NSCalendarUnitYear fromDate:[NSDate date]]; startComponents.day = 1; //the enumeration starts "afterDate", so shift the start back one day (86400 seconds) to include the 1st of the month NSDate *startDate = [[calendar dateFromComponents:startComponents] dateByAddingTimeInterval:-86400]; //the enumeration searches for a match; we'll match at the midnight hour and find every occurance of midnight NSDateComponents *dayByDay = [[NSDateComponents alloc] init]; dayByDay.hour = 0; //I've opted to put all matching weekdays of the month into an array, so you can find any instance easily __block NSMutableArray *foundDates = [NSMutableArray arrayWithCapacity:5]; [calendar enumerateDatesStartingAfterDate:startDate matchingComponents:dayByDay options:NSCalendarMatchPreviousTimePreservingSmallerUnits usingBlock:^(NSDate *date, BOOL exactMatch, BOOL *stop){ NSDateComponents *thisComponents = [calendar components:NSCalendarUnitMonth | NSCalendarUnitWeekday fromDate:date]; //as long as the month stays the same... (or the year, if you wanted to) if (thisComponents.month == startComponents.month) { //does this date match our target weekday search? if (thisComponents.weekday == targetWeekday) { //then add it to our result array [foundDates addObject:date]; } //once the month has changed, we're done } else { *stop = YES; } }]; //Now, with our search result array, we can find the 1st, last, or any specific occurance of that weekday on that month NSLog(@"Found these: %@", foundDates); 

Итак, если вы хотите только последний, просто используйте [foundDates lastObject]

Еще один способ решить. Найдите первый день следующего месяца, затем выполните поиск назад во вторник.

 let calendar = NSCalendar.currentCalendar() let today = NSDate() let components = calendar.components([.Year, .Month], fromDate: today) components.month += 1 // If today is 2016-07-12 then nextMonth will be the // first day of the next month: 2016-08-01 if let nextMonth = calendar.dateFromComponents(components) { // Search backwards for weekday = Tuesday let options: NSCalendarOptions = [.MatchPreviousTimePreservingSmallerUnits, .SearchBackwards] calendar.nextDateAfterDate(nextMonth, matchingUnit: .Weekday, value: 3, options: options) } 

Попробуйте этот код. Это работает для меня.

 NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; NSDateComponents *comps = [gregorian components:NSWeekdayCalendarUnit fromDate:[NSDate date]]; int weekday = [comps weekday]; int lastTues; int lastSatDay; if (weekday==1) { lastTues=5; lastSatDay=1; } else if (weekday==2) { lastTues=6; lastSatDay=2; } else if (weekday==3) { lastTues=7; lastSatDay=3; } else if (weekday==4) { lastTues=1; lastSatDay=4; } else if (weekday==5) { lastTues=2; lastSatDay=5; } else if (weekday==6) { lastTues=3; lastSatDay=6; } else if (weekday==7) { lastTues=4; lastSatDay=7; } NSDate *lastTuesDay = [[NSDate date] addTimeInterval:-3600*24*(lastTues)]; NSDate *lastSaturday = [[NSDate date] addTimeInterval:-3600*24*(lastSatDay)];