Istnieją dwie części to:
mam zamiar wyciągnąć z dwóch innych stanowiskach mi pomóc.
W weekendy będę potrzebować znać datę dnia danego dnia. Do tego, ten post jest przydatna: How to check what day of the week it is (i.e. Tues, Fri?) and compare two NSDates?
na święta, @vikingosegundo ma bardzo wielką sugestie na temat tego postu: List of all American holidays as NSDates
Najpierw zajmować weekendy;
byłem pochłonięty sugestię w poście wyżej cytowanej w tym ładnym małym funkcji pomocnika, który mówi nam, czy data jest dzień tygodnia:
BOOL isWeekday(NSDate * date)
{
int day = [[[NSCalendar currentCalendar] components:NSWeekdayCalendarUnit fromDate:date] weekday];
const int kSunday = 1;
const int kSaturday = 7;
BOOL isWeekdayResult = day != kSunday && day != kSaturday;
return isWeekdayResult;
}
Będziemy potrzebować sposób, aby zwiększyć datę przez daną liczbę dni:
NSDate * addDaysToDate(NSDate * date, int days)
{
NSDateComponents * components = [[NSDateComponents alloc] init];
[components setDay:days];
NSDate * result = [[NSCalendar currentCalendar] dateByAddingComponents:components toDate:date options:0];
[components release];
return result;
}
Musimy sposób pominąć weekendy:
NSDate * ensureDateIsWeekday(NSDate * date)
{
while (!isWeekday(date))
{
// Add one day to the date:
date = addDaysToDate(date, 1);
}
return date;
}
I musimy znaleźć sposób, aby dodać dowolną liczbę dni do daty:
NSDate * addBusinessDaysToDate(NSDate * start, int daysToAdvance)
{
NSDate * end = start;
for (int i = 0; i < daysToAdvance; i++)
{
// If the current date is a weekend, advance:
end = ensureDateIsWeekday(end);
// And move the date forward by one day:
end = addDaysToDate(end, 1);
}
// Finally, make sure we didn't end on a weekend:
end = ensureDateIsWeekday(end);
return end;
}
- Uwaga; Istnieje oczywista optymalizacja, którą pominąłem - możesz z łatwością dodać więcej niż jeden dzień do aktualnej daty - ale celem mojego posta jest pokazać ci, jak to zrobić samemu - i niekoniecznie wymyślić jak najlepsze rozwiązanie.
Teraz pozwala związać się i zobaczyć, że to, co mamy do tej pory:
int main() {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
NSDate * start = [NSDate date];
int daysToAdvance = 10;
NSDate * end = addBusinessDaysToDate(start, daysToAdvance);
NSLog(@"Result: %@", [end descriptionWithCalendarFormat:@"%Y-%m-%d"
timeZone:nil
locale:nil]);
[pool drain];
return 0;
}
Tak, mamy pokryte weekendy, teraz musimy ciągnąć w święta.
Ciągnięcie jakiegoś kanału RSS lub dane z innego źródła zdecydowanie wykraczają poza zakres mojego wpisu ... więc załóżmy, że masz pewne daty, o których wiesz, że są dniami świątecznymi lub, zgodnie z kalendarzem pracy, są dni poza.
Teraz zrobię to z NSArray ... ale, znowu, pozostawia to wiele do zrobienia - przynajmniej należy to posortować. Jeszcze lepiej, jakiś zestaw hash do szybkiego wyszukiwania dat. Ale ten przykład powinien wystarczyć do wyjaśnienia tej koncepcji. (Tutaj możemy skonstruować tablicę, która wskazuje, że są święta dwa i trzy dni od teraz)
NSMutableArray * holidays = [[NSMutableArray alloc] init];
[holidays addObject:addDaysToDate(start, 2)];
[holidays addObject:addDaysToDate(start, 3)];
I, realizacja tego będzie bardzo podobna do weekendów. Upewnimy się, że dzień nie jest świętem. Jeśli tak, przejdziemy do następnego dnia. Tak, to zbiór metod, aby pomóc z tym:
BOOL isHoliday(NSDate * date, NSArray * holidays)
{
BOOL isHolidayResult = NO;
const unsigned kUnits = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit;
NSDateComponents * components = [[NSCalendar currentCalendar] components:kUnits fromDate:date];
for (int i = 0; i < [holidays count]; i++)
{
NSDate * holiday = [holidays objectAtIndex:i];
NSDateComponents * holidayDateComponents = [[NSCalendar currentCalendar] components:kUnits fromDate:holiday];
if ([components year] == [holidayDateComponents year]
&& [components month] == [holidayDateComponents month]
&& [components day] == [holidayDateComponents day])
{
isHolidayResult = YES;
break;
}
}
return isHolidayResult;
}
i:
NSDate * ensureDateIsntHoliday(NSDate * date, NSArray * holidays)
{
while (isHoliday(date, holidays))
{
// Add one day to the date:
date = addDaysToDate(date, 1);
}
return date;
}
I wreszcie wprowadzić pewne modyfikacje do naszej funkcji oprócz uwzględnić święta:
NSDate * addBusinessDaysToDate(NSDate * start, int daysToAdvance, NSArray * holidays)
{
NSDate * end = start;
for (int i = 0; i < daysToAdvance; i++)
{
// If the current date is a weekend, advance:
end = ensureDateIsWeekday(end);
// If the current date is a holiday, advance:
end = ensureDateIsntHoliday(end, holidays);
// And move the date forward by one day:
end = addDaysToDate(end, 1);
}
// Finally, make sure we didn't end on a weekend or a holiday:
end = ensureDateIsWeekday(end);
end = ensureDateIsntHoliday(end, holidays);
return end;
}
Śmiało i spróbować go:
int main() {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
NSDate * start = [NSDate date];
int daysToAdvance = 10;
NSMutableArray * holidays = [[NSMutableArray alloc] init];
[holidays addObject:addDaysToDate(start, 2)];
[holidays addObject:addDaysToDate(start, 3)];
NSDate * end = addBusinessDaysToDate(start, daysToAdvance, holidays);
[holidays release];
NSLog(@"Result: %@", [end descriptionWithCalendarFormat:@"%Y-%m-%d"
timeZone:nil
locale:nil]);
[pool drain];
return 0;
}
Jeśli chcesz cały projekt, napisz: http://snipt.org/xolnl
przeskocz przez weekendy i święta siebie. –