我正在制作iPhone倒计时应用程序,需要知道一个周末(如周六和周日)将发生多少次,直到用户设置的日期。
一个例子是我如何才能找到从现在(8月6日星期一)到下周将会发生多少个周末? 我 知道答案是1个周末,但我需要能够使用代码解决这个问题。
我最接近的是使用NSDateComponents和NSCalender并做了接近以下的事情。
NSDateComponents *weekendsLeftComponents = [calendar components:NSWeekCalendarUnit
fromDate:targetDate
toDate:[NSDate date]
options:0];
但是从那里我已经击中了可怕的编码器墙,没有路过。
我的问题并不完全清楚如何去做。这听起来像阵列可以工作,但我担心阵列会变得相当大,因为这些“事情”中的一些可能长达几年。 (我正在制作一个应用程序,可以发现有多少天,周末等等,直到一个人毕业。)此外,我的观众主要是小孩到iPod的青少年,也是老年人。我不知道他们的记忆力(ram)在用完之前会有多充分。
提前非常感谢,
Alex Kafer
答案 0 :(得分:1)
您的fromDate
和toDate
似乎是向后的,假设将来会targetDate
。
以下是我如何解决这个问题。
在NSCalendar
上创建一个类别,以计算特定工作日在两个日期之间发生的次数:
@interface NSCalendar (AlexCategory)
// The number of times weekday number `weekday` (1 = Sunday, 7 = Saturday)
// occurs between `fromDate` and `toDate`. If `fromDate` falls on the desired
// weekday, it is counted. If `toDate` falls on the desired weekday, it is NOT counted.
- (NSInteger)countOfWeekday:(NSInteger)weekday fromDate:(NSDate *)fromDate toDate:(NSDate *)toDate;
@end
要实施这种新方法,我们首先要获取fromDate
的年,月,日和工作日:
@implementation NSCalendar (AlexCategory)
- (NSInteger)countOfWeekday:(NSInteger)weekday fromDate:(NSDate *)fromDate toDate:(NSDate *)toDate {
NSDateComponents *components = [self components:NSDayCalendarUnit | NSMonthCalendarUnit | NSYearCalendarUnit | NSWeekdayCalendarUnit fromDate:fromDate];
接下来,我们会计算从fromDate
到下一个所需工作日的天数:
NSInteger daysUntilDesiredWeekday = weekday - components.weekday;
// If fromDate is a Wednesday and weekday is Monday (for example),
// daysUntilDesiredWeekday is negative. Fix that.
NSRange weekdayRange = [self minimumRangeOfUnit:NSWeekdayCalendarUnit];
if (daysUntilDesiredWeekday < weekdayRange.location) {
daysUntilDesiredWeekday += weekdayRange.length;
}
请注意,如果daysUntilDesiredWeekday
落在所需的工作日,fromDate
将为零。
现在,我们可以在NSDateComponents
之后创建代表第一个所需工作日的fromDate
:
NSDateComponents *firstDesiredWeekday = [[NSDateComponents alloc] init];
firstDesiredWeekday.year = components.year;
firstDesiredWeekday.month = components.month;
firstDesiredWeekday.day = components.day + daysUntilDesiredWeekday;
我们将fromDate
更新为第一个所需的工作日,如果它在toDate
之后或之后返回0:
fromDate = [self dateFromComponents:firstDesiredWeekday];
if ([fromDate compare:toDate] != NSOrderedAscending) {
return 0;
}
接下来,我们会计算从更新后的fromDate
到toDate
的所有日期(不仅仅是所需的工作日):
NSInteger allDaysCount = [self components:NSDayCalendarUnit
fromDate:fromDate toDate:toDate options:0].day;
我们可以将它除以一周中的天数来计算所需工作日的数量。由于我们从期望的工作日开始计算,因此任何部分周余数也将包含所需的工作日,因此我们需要进行整理:
// Adding weekdayRange.length - 1 makes the integer division round up.
return (allDaysCount + weekdayRange.length - 1) / weekdayRange.length;
}
@end
我们可以测试这样的方法:
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *components = [[NSDateComponents alloc] init];
components.year = 2012;
components.month = 1;
components.day = 1;
NSDate *fromDate = [calendar dateFromComponents:components];
for (NSUInteger i = 1; i <= 365; ++i) {
components.day = i;
NSDate *toDate = [calendar dateFromComponents:components];
NSLog(@"%@ to %@: %ld Mondays", fromDate, toDate, [calendar countOfWeekday:2 fromDate:fromDate toDate:toDate]);
}
输出开头如下:
2012-08-06 16:27:05.751 tuesdays[81152:403] 0 Mondays from 2012-01-01 06:00:00 +0000 to 2012-01-01 06:00:00 +0000
2012-08-06 16:27:05.754 tuesdays[81152:403] 0 Mondays from 2012-01-01 06:00:00 +0000 to 2012-01-02 06:00:00 +0000
2012-08-06 16:27:05.756 tuesdays[81152:403] 1 Mondays from 2012-01-01 06:00:00 +0000 to 2012-01-03 06:00:00 +0000
2012-08-06 16:27:05.758 tuesdays[81152:403] 1 Mondays from 2012-01-01 06:00:00 +0000 to 2012-01-04 06:00:00 +0000
2012-08-06 16:27:05.759 tuesdays[81152:403] 1 Mondays from 2012-01-01 06:00:00 +0000 to 2012-01-05 06:00:00 +0000
2012-08-06 16:27:05.760 tuesdays[81152:403] 1 Mondays from 2012-01-01 06:00:00 +0000 to 2012-01-06 06:00:00 +0000
2012-08-06 16:27:05.762 tuesdays[81152:403] 1 Mondays from 2012-01-01 06:00:00 +0000 to 2012-01-07 06:00:00 +0000
2012-08-06 16:27:05.763 tuesdays[81152:403] 1 Mondays from 2012-01-01 06:00:00 +0000 to 2012-01-08 06:00:00 +0000
2012-08-06 16:27:05.763 tuesdays[81152:403] 1 Mondays from 2012-01-01 06:00:00 +0000 to 2012-01-09 06:00:00 +0000
2012-08-06 16:27:05.764 tuesdays[81152:403] 2 Mondays from 2012-01-01 06:00:00 +0000 to 2012-01-10 06:00:00 +0000
2012-08-06 16:27:05.765 tuesdays[81152:403] 2 Mondays from 2012-01-01 06:00:00 +0000 to 2012-01-11 06:00:00 +0000
根据cal 1 2012
:
January 2012
Su Mo Tu We Th Fr Sa
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
(请记住,toDate
不计算在内,所以从2012-1-1到2012-1-2有0个星期一,即使2012-1-2是星期一。)
答案 1 :(得分:0)
您需要指定问题。 定义什么是周末?对我来说周末是周六和周日。因此,每当星期天出现这是一个周末(请记住,周日不是整个周末 - 我只是想简化要求)。
那你怎么能在代码中做到这一点? 有很多方法。一种快速的方法是创建一个包含每天[星期一,星期二,......,星期日]
的数组现在您想知道本周二和周二之间在3周内会出现多少个周末。您将通过减去targetDateComponent.week-currentDateComponent.week
获得数字3。你只需要经历这个阵列,直到星期二出现3次并计算所有星期天。
真的很简单。我不确定这是否完全符合你的问题。但有很多方法。
试着谨慎思考