gpt4 book ai didi

objective-c - 我如何将工作日添加到 NSDate?

转载 作者:太空狗 更新时间:2023-10-30 03:39:09 26 4
gpt4 key购买 nike

我有一个与在 Objective-C 中计算工作日相关的问题。

我需要将 X 个工作日添加到给定的 NSDate

例如,如果我有一个日期:2010 年 10 月 22 日,星期五,然后添加 2 个工作日,我应该得到:26 日星期二- 2010 年 10 月

提前致谢。

最佳答案

这有两个部分:

  • 周末
  • 节假日

我将从另外两个帖子中提取信息来帮助我。

对于周末,我需要知道给定日期是星期几。为此,这篇文章派上用场了: How to check what day of the week it is (i.e. Tues, Fri?) and compare two NSDates?

对于假期,@vikingosegundo 在这篇文章中有一个非常好的建议: List of all American holidays as 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;
}

我们需要一种方法将日期增加给定的天数:

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;
}

我们需要一种跳过周末的方法:

NSDate * ensureDateIsWeekday(NSDate * date)
{
while (!isWeekday(date))
{
// Add one day to the date:
date = addDaysToDate(date, 1);
}

return date;
}

我们需要一种方法来为日期添加任意天数:

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;
}
  • 注意;我跳过了一个明显的优化——你可以很容易地在当前日期中一次添加不止一天——但我这篇文章的重点是向你展示如何自己做这件事——而不一定是想出最好的可能解决方案。

现在让我们把它联系起来,看看到目前为止我们有什么:

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;
}

所以,我们已经有周末了,现在我们需要把假期拉回来。

引入一些 RSS 提要或来自其他来源的数据绝对超出了我的帖子范围...因此,我们假设您知道某些日期是假期,或者根据您的工作日历,是休息日.

现在,我将使用 NSArray 来执行此操作...但是,同样,这也留下了很大的改进空间 - 至少应该对它进行排序。更好的是,某种用于快速查找日期的哈希集。但是,这个例子应该足以解释这个概念。 (这里构造了一个数组,表示从现在开始两三天后有假期)

NSMutableArray * holidays = [[NSMutableArray alloc] init];
[holidays addObject:addDaysToDate(start, 2)];
[holidays addObject:addDaysToDate(start, 3)];

而且,这方面的实现将与周末非常相似。我们会确保这一天不是假期。如果是,我们将提前到第二天。因此,一组方法可以帮助解决这个问题:

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;
}

和:

NSDate * ensureDateIsntHoliday(NSDate * date, NSArray * holidays)
{
while (isHoliday(date, holidays))
{
// Add one day to the date:
date = addDaysToDate(date, 1);
}

return date;
}

最后,对我们的加法函数进行一些修改以考虑假期:

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;
}

继续尝试:

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;
}

如果你想要整个项目,这里是:http://snipt.org/xolnl

关于objective-c - 我如何将工作日添加到 NSDate?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7871435/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com