Cocoa 我怎样才能获得本月下一周第一天的NSDate
给定任意日期,我需要找到该月下一周第一天的日期。请注意,这并不像向当前日期添加7天那么简单,因为一个月的最后一周可能少于7天。下面是我现在使用的代码:Cocoa 我怎样才能获得本月下一周第一天的NSDate,cocoa,nsdate,nscalendar,nsdatecomponents,Cocoa,Nsdate,Nscalendar,Nsdatecomponents,给定任意日期,我需要找到该月下一周第一天的日期。请注意,这并不像向当前日期添加7天那么简单,因为一个月的最后一周可能少于7天。下面是我现在使用的代码: NSCalendar* calendar = [NSCalendar currentCalendar]; NSDateComponents* components = [calendar components:NSWeekOfMonthCalendarUnit|NSYearCalendarUnit|NSMonthCalendarU
NSCalendar* calendar = [NSCalendar currentCalendar];
NSDateComponents* components = [calendar components:NSWeekOfMonthCalendarUnit|NSYearCalendarUnit|NSMonthCalendarUnit|NSWeekCalendarUnit|NSDayCalendarUnit fromDate:currentDate];
NSLog(@"week of month: %ld", [components weekOfMonth]);
[components setWeekOfMonth:[components weekOfMonth] + 1];
NSLog(@"new week of month: %ld", [components weekOfMonth]); //week of month is now 2
[components setWeekday:1];
NSDate *nextWeek = [calendar dateFromComponents:components];
例如,currentDate设置为2012-10-01。在本例中,nextWeek始终为2012-10-01。似乎发送
setWeekOfMonth:
不会增加NSDateComponents
对象中的其他日期组件。我是否配置了错误的日期组件,或者setWeekOfMonth:
不应该这样工作?所以。。。。让我们从一个NSDate
和一个NSCalendar
开始:
NSDate *date = ...;
NSCalendar *cal = [NSCalendar currentCalendar];
计算出该日期是一周中的哪一天:
NSInteger weekdayOfDate = [cal ordinalityOfUnit:NSWeekdayCalendarUnit inUnit:NSWeekCalendarUnit forDate:date];
NSInteger numberOfDaysToStartOfCurrentWeek = weekdayOfDate - 1;
让我们将该日期移到下周:
NSDateComponents *oneWeek = [[NSDateComponents alloc] init];
[oneWeek setWeek:1]; // add one week
[oneWeek setDay:-numberOfDaysToStartOfCurrentWeek]; // ... and subtract a couple of days to get the first day of the week
NSDate *startOfNextWeek = [cal dateByAddingComponents:oneWeek toDate:date options:0];
此时,您有一个指向下周第一天的日期。现在我们应该确认它仍然在同一个月内:
NSDateComponents *monthOfNextWeek = [cal components:NSMonthCalendarUnit fromDate:startOfNextWeek];
NSDateComponents *monthOfThisWeek = [cal components:NSMonthCalendarUnit fromDate:date];
if ([monthOfNextWeek month] != [monthOfThisWeek month]) {
// the first day of the next week is not in the same month as the start date
}
当我运行这个程序时,我知道下周的开始时间是2012年12月30日(一个周日,因为我的日历周从周日开始)
但是,如果我希望一周的第一天从星期一开始,我可以在代码前面加上:
[cal setFirstWeekday:2]; // the first day of the week is the second day (ie, Monday, because Sunday = 1)
如果我这样做,那么下一周的开始日期将在2012年12月31日。。。。让我们从一个
NSDate
和一个NSCalendar
开始:
NSDate *date = ...;
NSCalendar *cal = [NSCalendar currentCalendar];
计算出该日期是一周中的哪一天:
NSInteger weekdayOfDate = [cal ordinalityOfUnit:NSWeekdayCalendarUnit inUnit:NSWeekCalendarUnit forDate:date];
NSInteger numberOfDaysToStartOfCurrentWeek = weekdayOfDate - 1;
让我们将该日期移到下周:
NSDateComponents *oneWeek = [[NSDateComponents alloc] init];
[oneWeek setWeek:1]; // add one week
[oneWeek setDay:-numberOfDaysToStartOfCurrentWeek]; // ... and subtract a couple of days to get the first day of the week
NSDate *startOfNextWeek = [cal dateByAddingComponents:oneWeek toDate:date options:0];
此时,您有一个指向下周第一天的日期。现在我们应该确认它仍然在同一个月内:
NSDateComponents *monthOfNextWeek = [cal components:NSMonthCalendarUnit fromDate:startOfNextWeek];
NSDateComponents *monthOfThisWeek = [cal components:NSMonthCalendarUnit fromDate:date];
if ([monthOfNextWeek month] != [monthOfThisWeek month]) {
// the first day of the next week is not in the same month as the start date
}
当我运行这个程序时,我知道下周的开始时间是2012年12月30日(一个周日,因为我的日历周从周日开始)
但是,如果我希望一周的第一天从星期一开始,我可以在代码前面加上:
[cal setFirstWeekday:2]; // the first day of the week is the second day (ie, Monday, because Sunday = 1)
如果我这样做,那么下一周的启动将于2012年12月31日生效。这是否是一个有效的答案:
NSDateFormatter *dateFormatter=[NSDateFormatter new];
[dateFormatter setLocale:[[NSLocale alloc]initWithLocaleIdentifier:@"en_US_POSIX"]];
[dateFormatter setDateFormat:@"EEE"];
NSDate *date=[NSDate date];
NSString *dateString=[dateFormatter stringFromDate:date];
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier: NSGregorianCalendar];
NSDateComponents *components = [NSDateComponents new];
[calendar setFirstWeekday:1];//1 for Mon
NSDate *newDate=date;
while (![dateString isEqualToString:@"Mon"]) {
components.day = 1;
newDate = [calendar dateByAddingComponents:components toDate:newDate options:0];
dateString=[dateFormatter stringFromDate:newDate];
}
NSLog(@"Upcoming week Date=%@",newDate);
这是否一个有效的答案:
NSDateFormatter *dateFormatter=[NSDateFormatter new];
[dateFormatter setLocale:[[NSLocale alloc]initWithLocaleIdentifier:@"en_US_POSIX"]];
[dateFormatter setDateFormat:@"EEE"];
NSDate *date=[NSDate date];
NSString *dateString=[dateFormatter stringFromDate:date];
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier: NSGregorianCalendar];
NSDateComponents *components = [NSDateComponents new];
[calendar setFirstWeekday:1];//1 for Mon
NSDate *newDate=date;
while (![dateString isEqualToString:@"Mon"]) {
components.day = 1;
newDate = [calendar dateByAddingComponents:components toDate:newDate options:0];
dateString=[dateFormatter stringFromDate:newDate];
}
NSLog(@"Upcoming week Date=%@",newDate);
假设您的一周从周一开始,今天是12月27日,那么您希望12月31日作为您的答案?是的,这是正确的,假设currentCalenar设置为使用周一作为一周的第一天。如果设置星期天为一周的第一天,那么下一周将是12月30日。StackOverflow:@MikeT:我已经发布了另一个答案,请告诉我,这是否正确?假设你的一周从星期一开始,今天是12月27日,那么你希望12月31日作为你的答案?是的,没错,假设currentCalenar设置为使用星期一作为一周的第一天。如果设定星期天为一周的第一天,那么下一周将是12月30日。StackOverflow:@MikeT:我已经发布了另一个答案,请告诉我,这是否正确?你能解释一下为什么从工作日减去1吗?我不明白这是怎么让你知道本周开始的天数的。接下来我会尽快实现它,看看它是如何工作的。@MikeT基本上,因为工作日是基于1的,而不是基于0的。代码所做的是在一个步骤中进行两次计算:首先加上一周,然后减去足够的天数,直到下一周开始
NSDateComponents
方便地让我们一步就可以完成。因此,如果date
对应于一个星期日(工作日1),那么NumberOfDaysToStarToCurrentWeek
就是1-1
,或者0
(因为它已经是当前星期的开始)。因此,加上一周,减去0天,就可以进入下一周的开始。除了我使用了[oneWeek setDay:[oneWeek day]-NumberOfDays ToStartOfCurrentWeek];所以那一天永远不会结束0@MikeT将其设置为0就可以了。但是,如果您不想将其设置为0,您应该执行如果(numberOfDaysToStartOfCurrentWeek>0){…}
您能解释一下为什么从工作日日期中减去1吗?我不明白这是怎么让你知道本周开始的天数的。接下来我会尽快实现它,看看它是如何工作的。@MikeT基本上,因为工作日是基于1的,而不是基于0的。代码所做的是在一个步骤中进行两次计算:首先加上一周,然后减去足够的天数,直到下一周开始NSDateComponents
方便地让我们一步就可以完成。因此,如果date
对应于一个星期日(工作日1),那么NumberOfDaysToStarToCurrentWeek
就是1-1
,或者0
(因为它已经是当前星期的开始)。因此,加上一周,减去0天,就可以进入下一周的开始。除了我使用了[oneWeek setDay:[oneWeek day]-NumberOfDays ToStartOfCurrentWeek];所以那一天永远不会结束0@MikeT将其设置为0就可以了。但是,如果不想将其设置为0,则应执行如果(NumberOfDaysToStarToCurrentWeek>0){…}
如果执行此操作,还必须将dateFormatter的语言环境设置为en_US_POSIX
,因为此代码将根据系统的语言环境而中断。(例如,如果这是在讲西班牙语的系统上运行的,@“EEE”
将呈现为@“Lun”
,而不是@“Mon”
)@DaveDeLong:OMG。。。我真的很高兴从苏和你身上学到很多东西。谢谢,先生。我将更新答案。如果您这样做,还必须将dateFormatter的区域设置设置为en_US\u POSIX
,因为此代码将根据系统的区域设置而中断。(例如,如果这是在讲西班牙语的系统上运行的,@“EEE”
将呈现为@“Lun”
,而不是@“Mon”
)@DaveDeLong:OMG。。。我真的很高兴从苏和你身上学到很多东西。谢谢,先生。我会更新答案。