Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/iphone/38.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Iphone 查找从现在到目标日期每天将出现多少次_Iphone_Nscalendar_Nsdatecomponents_Weekend - Fatal编程技术网

Iphone 查找从现在到目标日期每天将出现多少次

Iphone 查找从现在到目标日期每天将出现多少次,iphone,nscalendar,nsdatecomponents,weekend,Iphone,Nscalendar,Nsdatecomponents,Weekend,我正在制作一个iPhone倒计时应用程序,需要知道在用户设定日期之前,每个周末(如周六和周日)会发生多少次 例如,我如何确定从现在(8月6日,星期一)到下周有多少个周末我知道答案是1个周末,但我需要能够使用代码解决这个问题 我得到的最接近的结果是使用NSDateComponents和NSCalender,并做一些类似于以下的事情 NSDateComponents *weekendsLeftComponents = [calendar components:NSWeekCalendarUnit

我正在制作一个iPhone倒计时应用程序,需要知道在用户设定日期之前,每个周末(如周六和周日)会发生多少次

例如,我如何确定从现在(8月6日,星期一)到下周有多少个周末知道答案是1个周末,但我需要能够使用代码解决这个问题

我得到的最接近的结果是使用NSDateComponents和NSCalender,并做一些类似于以下的事情

NSDateComponents *weekendsLeftComponents = [calendar components:NSWeekCalendarUnit
                                                    fromDate:targetDate
                                                      toDate:[NSDate date]
                                                     options:0];
但从那以后,我就撞上了可怕的编码墙——禁止通行

我的问题是不知道该怎么做。这听起来像是一个阵列可以工作,但我担心阵列可能会变得相当大,因为其中一些“东西”可能长达几年。(我正在制作一个应用程序,可以知道一个人毕业前有多少天、周末等。)同时,我的受众主要是使用iPod的儿童到青少年,还有年纪较大的人。我不知道他们的内存(ram)在用完之前会有多满

提前非常感谢你


Alex Kafer

您需要指定您的问题。 定义什么是周末?对我来说,周末是周六和周日。因此,每当一个星期天出现时,它就是一个周末(请记住,星期天并不是整个周末——我只想简化要求)

那么,如何在代码中实现这一点呢? 有很多方法。一种快速方法是创建一个数组,其中包含每一天[周一、周二、…、周日]

现在,您想知道在3周内本周二和周二之间出现了多少个周末。通过减去
targetDateComponent.week currentDateComponent.week
得到数字3。你只需通过这个数组,直到星期二出现3次,并计算所有的星期天

真的很简单。我不确定这是否完全符合你的问题。但是有很多方法


只要试着谨慎地想一想,你的
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];
    NSDateComponents *firstDesiredWeekday = [[NSDateComponents alloc] init];
    firstDesiredWeekday.year = components.year;
    firstDesiredWeekday.month = components.month;
    firstDesiredWeekday.day = components.day + daysUntilDesiredWeekday;
    fromDate = [self dateFromComponents:firstDesiredWeekday];
    if ([fromDate compare:toDate] != NSOrderedAscending) {
        return 0;
    }
    NSInteger allDaysCount = [self components:NSDayCalendarUnit
        fromDate:fromDate toDate:toDate options:0].day;
接下来,我们计算从
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;
    }
我们将
fromDate
更新为所需的第一个工作日,如果在
toDate
上或之后,则返回0:

@implementation NSCalendar (AlexCategory)

- (NSInteger)countOfWeekday:(NSInteger)weekday fromDate:(NSDate *)fromDate toDate:(NSDate *)toDate {
    NSDateComponents *components = [self components:NSDayCalendarUnit | NSMonthCalendarUnit | NSYearCalendarUnit | NSWeekdayCalendarUnit fromDate:fromDate];
    NSDateComponents *firstDesiredWeekday = [[NSDateComponents alloc] init];
    firstDesiredWeekday.year = components.year;
    firstDesiredWeekday.month = components.month;
    firstDesiredWeekday.day = components.day + daysUntilDesiredWeekday;
    fromDate = [self dateFromComponents:firstDesiredWeekday];
    if ([fromDate compare:toDate] != NSOrderedAscending) {
        return 0;
    }
    NSInteger allDaysCount = [self components:NSDayCalendarUnit
        fromDate:fromDate toDate:toDate options:0].day;
接下来,我们计算从更新的
fromDate
toDate
的所有天数(不仅仅是期望的工作日):

@implementation NSCalendar (AlexCategory)

- (NSInteger)countOfWeekday:(NSInteger)weekday fromDate:(NSDate *)fromDate toDate:(NSDate *)toDate {
    NSDateComponents *components = [self components:NSDayCalendarUnit | NSMonthCalendarUnit | NSYearCalendarUnit | NSWeekdayCalendarUnit fromDate:fromDate];
    NSDateComponents *firstDesiredWeekday = [[NSDateComponents alloc] init];
    firstDesiredWeekday.year = components.year;
    firstDesiredWeekday.month = components.month;
    firstDesiredWeekday.day = components.day + daysUntilDesiredWeekday;
    fromDate = [self dateFromComponents:firstDesiredWeekday];
    if ([fromDate compare:toDate] != NSOrderedAscending) {
        return 0;
    }
    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是星期一。)

在这种情况下,您是对的,数组可以创建更长的运行时间。但是一个7天的数组在两个日期之间的几周内迭代,它也应该有一个O(n)运行时,这意味着它相当快。。。但我可能错了。内存不会是问题,因为您只在阵列上使用。不确定是否有其他方法,但有几个“日历”问题,请立即解决!为了清楚起见,如果我想将它从周一改为周日,我会将工作日数从2改为1。对的