mil*_*ari 6 objective-c core-foundation
我有一个与计算Objective-C中的工作日有关的问题.
我需要为X
给定的工作日添加工作日NSDate
.
例如,如果我有一个日期:2010年10月22日星期五,我加上2个工作日,我应该得到:2010年10月26日星期二.
提前致谢.
Ste*_*eve 20
这有两个部分:
我要从其他两个帖子中拉出来帮助我.
对于周末,我需要知道一周中某个特定日期.为此,这篇文章派上用场: 如何查看一周中的哪一天(即星期二,星期五?)并比较两个NSDates?
对于假期,@ vikingosegundo对这篇文章提出了非常好的建议: 所有美国假期列表为NSDates
首先,让我们来处理周末;
我把上面引用的帖子中的建议结合到这个漂亮的小助手函数中,该函数告诉我们日期是否是工作日:
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;
}
Run Code Online (Sandbox Code Playgroud)
我们需要一种方法来将日期递增给定的天数:
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;
}
Run Code Online (Sandbox Code Playgroud)
我们需要一种方法来跳过周末:
NSDate * ensureDateIsWeekday(NSDate * date)
{
while (!isWeekday(date))
{
// Add one day to the date:
date = addDaysToDate(date, 1);
}
return date;
}
Run Code Online (Sandbox Code Playgroud)
我们需要一种方法来为日期添加任意天数:
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;
}
Run Code Online (Sandbox Code Playgroud)
现在让我们把它绑起来看看到目前为止我们有什么:
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;
}
Run Code Online (Sandbox Code Playgroud)
所以,我们有周末,现在我们需要拉假期.
拉入一些RSS提要或来自其他来源的数据肯定超出了我的帖子的范围......所以,我们假设您有一些您知道的假期日期,或者根据您的工作日历,这些日期是休假.
现在,我将使用NSArray来做这件事......但是,这仍然有很大的改进空间 - 至少它应该被排序.更好的是,某种哈希集用于快速查找日期.但是,这个例子应该足以解释这个概念.(这里我们构造一个数组,表明从现在起两到三天都有假期)
NSMutableArray * holidays = [[NSMutableArray alloc] init];
[holidays addObject:addDaysToDate(start, 2)];
[holidays addObject:addDaysToDate(start, 3)];
Run Code Online (Sandbox Code Playgroud)
并且,此实施将与周末非常相似.我们将确保这一天不是假期.如果是,我们将提前到第二天.所以,一组方法来帮助:
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;
}
Run Code Online (Sandbox Code Playgroud)
和:
NSDate * ensureDateIsntHoliday(NSDate * date, NSArray * holidays)
{
while (isHoliday(date, holidays))
{
// Add one day to the date:
date = addDaysToDate(date, 1);
}
return date;
}
Run Code Online (Sandbox Code Playgroud)
最后,对我们的添加功能进行一些修改以考虑假期:
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;
}
Run Code Online (Sandbox Code Playgroud)
继续尝试:
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;
}
Run Code Online (Sandbox Code Playgroud)
如果您想要整个项目,请访问:http://snipt.org/xolnl
归档时间: |
|
查看次数: |
3847 次 |
最近记录: |