NSCalendar每周的第一天

有谁知道是否有办法在NSCalendar上设置一周的第一天,或者是否有一个日历已经有星期一作为一周的第一天,而不是星期天。 我目前正在开发基于一周工作量的应用程序,它需要在星期一而不是星期天开始。 我很可能会做一些工作来解决这个问题,但是会有很多的情况。 我宁愿平台为我做。

提前致谢

这里有一些我正在使用的代码。 现在是星期六,所以我希望那个星期几是6,而不是7,那意味着星期天是7,而不是滚到0

NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; [gregorian setFirstWeekday:0]; unsigned unitFlags = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit | NSWeekCalendarUnit | NSWeekdayCalendarUnit; NSDateComponents *todaysDate = [gregorian components:unitFlags fromDate:[NSDate date]]; int dayOfWeek = todaysDate.weekday; 

编辑:这不检查在上个月开始一周的边缘情况。 一些更新的代码来覆盖这个: https : //stackoverflow.com/a/14688780/308315


如果有人仍然关注这个,你需要使用

 ordinalityOfUnit:inUnit:forDate: 

并设置第一个周日到2(1 ==星期天和7 ==星期六)

代码如下:

 NSCalendar *gregorian = [[[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar] autorelease]; [gregorian setFirstWeekday:2]; // Sunday == 1, Saturday == 7 NSUInteger adjustedWeekdayOrdinal = [gregorian ordinalityOfUnit:NSWeekdayCalendarUnit inUnit:NSWeekCalendarUnit forDate:[NSDate date]]; NSLog(@"Adjusted weekday ordinal: %d", adjustedWeekdayOrdinal); 

请记住,星期一的星期一的起点为1,而不是零。

文档链接 。

此代码构build一个设置为当前星期一的date:

 NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; NSDate *today = [NSDate date]; NSDate *beginningOfWeek = nil; BOOL ok = [gregorian rangeOfUnit:NSWeekCalendarUnit startDate:&beginningOfWeek interval:NULL forDate: today]; 

setFirstWeekday:在NSCalendar对象上。 设置接收者第一个工作日的索引。

 - (void)setFirstWeekday:(NSUInteger)weekday 

应该做的伎俩。

在我看来,这个设置应该是根据用户区域dynamic的。 所以应该使用:

 NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; [gregorian setLocale:[NSLocale currentLocale]]; 

这将导致日历根据用户区域设置自动设置第一个星期的一天。 除非您正在为特定目的/用户区域设置开发应用程序(或者更愿意允许用户select这一天)。

克里斯的答案的问题是一周的开始在前一个月的边缘情况。 这里有一些简单的代码,它也检查边缘情况:

 // Finds the date for the first day of the week - (NSDate *)getFirstDayOfTheWeekFromDate:(NSDate *)givenDate { NSCalendar *calendar = [NSCalendar currentCalendar]; // Edge case where beginning of week starts in the prior month NSDateComponents *edgeCase = [[NSDateComponents alloc] init]; [edgeCase setMonth:2]; [edgeCase setDay:1]; [edgeCase setYear:2013]; NSDate *edgeCaseDate = [calendar dateFromComponents:edgeCase]; NSDateComponents *components = [calendar components:NSYearCalendarUnit|NSMonthCalendarUnit|NSWeekCalendarUnit|NSWeekdayCalendarUnit fromDate:edgeCaseDate]; [components setWeekday:1]; // 1 == Sunday, 7 == Saturday [components setWeek:[components week]]; NSLog(@"Edge case date is %@ and beginning of that week is %@", edgeCaseDate , [calendar dateFromComponents:components]); // Find Sunday for the given date components = [calendar components:NSYearCalendarUnit|NSMonthCalendarUnit|NSWeekCalendarUnit|NSWeekdayCalendarUnit fromDate:givenDate]; [components setWeekday:1]; // 1 == Sunday, 7 == Saturday [components setWeek:[components week]]; NSLog(@"Original date is %@ and beginning of week is %@", givenDate , [calendar dateFromComponents:components]); return [calendar dateFromComponents:components]; } 

我已经这样做了。

 NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; NSDate *today = [NSDate date]; NSDateComponents *compForWeekday = [gregorian components:(NSWeekdayCalendarUnit) fromDate:today]; NSInteger weekDayAsNumber = [compForWeekday weekday]; // The week day as number but with sunday starting as 1 weekDayAsNumber = ((weekDayAsNumber + 5) % 7) + 1; // Transforming so that monday = 1 and sunday = 7 

我在这里遇到了很多答案。 。 也许这只是我。 。

这是一个适合我的答案:

 - (NSDate*)firstDayOfWeek { NSCalendar* cal = [[NSCalendar currentCalendar] copy]; [cal setFirstWeekday:2]; //Override locale to make week start on Monday NSDate* startOfTheWeek; NSTimeInterval interval; [cal rangeOfUnit:NSWeekCalendarUnit startDate:&startOfTheWeek interval:&interval forDate:self]; return startOfTheWeek; } - (NSDate*)lastDayOfWeek { NSCalendar* cal = [[NSCalendar currentCalendar] copy]; [cal setFirstWeekday:2]; //Override locale to make week start on Monday NSDate* startOfTheWeek; NSTimeInterval interval; [cal rangeOfUnit:NSWeekCalendarUnit startDate:&startOfTheWeek interval:&interval forDate:self]; return [startOfTheWeek dateByAddingTimeInterval:interval - 1]; } 

更新:

正如@vikingosegundo( 其他地方 )所指出的那样,一般来说最好让本地决定哪一天是一周的开始,然而在这种情况下,OP要求周一开始发生,因此我们复制系统日历,并覆盖第一个周日。

我在其他信息中看到了误解。 第一个工作日,以数字1为准。默认星期天= 1,如“cocoadate和时间编程指南简介:日历计算”中所示:

“公历周日的平日价值为1”

对于星期一作为第一个工作日我唯一的补救措施是蛮力条件来解决计算

 NSCalendar *cal=[[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; NSDateComponents *comps = [cal components:NSWeekdayCalendarUnit fromDate:[NSDate date]]; // set to 7 if it's Sunday otherwise decrease weekday number NSInteger weekday=[comps weekday]==1?7:[comps weekday]-1; 

下面还介绍边缘情况,

 - (NSDate *)getFirstDayOfTheWeekFromDate:(NSDate *)givenDate { NSCalendar *calendar = [NSCalendar currentCalendar]; NSDateComponents *components = [calendar components:NSYearCalendarUnit|NSMonthCalendarUnit|NSWeekCalendarUnit|NSWeekdayCalendarUnit fromDate:givenDate]; [components setWeekday:2]; // 1 == Sunday, 7 == Saturday if([[calendar dateFromComponents:components] compare: curDate] == NSOrderedDescending) // if start is later in time than end { [components setWeek:[components week]-1]; } return [calendar dateFromComponents:components]; } 

尝试这个:

 NSCalendar *yourCal = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar] [yourCal setFirstWeekday:0]; 

…有一个日历已经有一个星期一,而不是星期天。

有一天会有的

我find了使用nscalender显示任何周日名称的方法..使用下面的代码..只要打开你的控制台从xcode菜单栏来查看results.Copy粘贴下面的代码在你的viewDidLoad方法来获得一周的第一天

 NSDate *today = [NSDate date]; NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init]; [dateFormat setDateFormat:@"MM/dd/yyyy :EEEE"]; NSString *dateString = [dateFormat stringFromDate:today]; NSLog(@"date: %@", dateString); [dateFormat release]; NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; NSDateComponents *components = [gregorian components:NSWeekdayCalendarUnit | NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit fromDate:today]; [components setDay:([components day]-([components weekday]-1))]; NSDate *beginningOfWeek = [gregorian dateFromComponents:components]; NSDateFormatter *dateFormat_first = [[NSDateFormatter alloc] init]; [dateFormat_first setDateFormat:@"MM/dd/yyyy :EEEE"]; NSString *dateString_first = [dateFormat_first stringFromDate:beginningOfWeek]; NSLog(@"First_date: %@", dateString_first); 

输出将是:

  date: 02/11/2010 :Thursday First_date: 02/07/2010 :Sunday 

因为我已经在2/11/2010运行这个程序,你会得到所需的输出取决于当前的date。

同样,如果你想得到一周的第一个工作日,即星期一的date,那么就修改一下代码:

CHANGE: [components setDay:([components day]-([components weekday]-1))];

TO [components setDay:([components day]-([components weekday]-2))];

获得星期一的date

同样,你可以尝试通过改变整数-1,-2等来find七个工作日中的任何一个的date…

希望你的问题被回答..

谢谢Bonson Dias

我这样做的简单方法是星期一= 0,星期天= 6:

  NSDateComponents *dateComponents = [[NSCalendar currentCalendar] components:NSWeekdayCalendarUnit fromDate:[NSDate date]]; NSInteger dayNumStartingFromMonday = ([dateComponents weekday] - 2 + 7) % 7; //normal: Sunday is 1, Monday is 2 

ISO 8601日历默认情况下星期一设置为星期一。

使用日历nextWeekend (iOS 10或更高版本)和正常(谢谢@ kris-markel)。 我星期一是en_US日历的第一周。

以下是第一个周一回退的例子:

 extension Calendar { var firstWorkWeekday: Int { guard #available(iOS 10.0, *) else{ return self.firstWeekday } guard let endOfWeekend = self.nextWeekend(startingAfter: Date())?.end else { return self.firstWeekday } return self.ordinality(of: .weekday, in: .weekOfYear, for: endOfWeekend) ?? self.firstWeekday } } 

您可以只更改.firstWeekday的第一个.firstWeekday

 NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian]; calendar.firstWeekday = 2; 

然后使用rangeOfUnit:startDate:interval:forDate:获取第一天

 NSDate *startOfWeek; [calendar rangeOfUnit:NSCalendarUnitWeekOfYear startDate:&startOfWeek interval:nil forDate:[NSdate date]];