NSCalendar第一天的第一天

Jos*_*hua 43 iphone cocoa calendar weekday nscalendar

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

提前致谢

这是我正在使用的一些代码.现在是星期六,所以我希望工作日是6而不是7,这意味着星期日将是7而不是0到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;
Run Code Online (Sandbox Code Playgroud)

Kri*_*kel 77

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


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

ordinalityOfUnit:inUnit:forDate:
Run Code Online (Sandbox Code Playgroud)

并将firstWeekday设为2.(1 == Sunday和7 == Saturday)

这是代码:

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);
Run Code Online (Sandbox Code Playgroud)

请记住,工作日的序数从一周的第一天开始为1,而不是零.

文档链接.

  • @Joshua这是正确答案,请核实并核实答案. (3认同)

Ken*_*ner 18

此代码构造一个设置为当前周的星期一的日期:

NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];

NSDate *today = [NSDate date];
NSDate *beginningOfWeek = nil;
BOOL ok = [gregorian rangeOfUnit:NSWeekCalendarUnit startDate:&beginningOfWeek
                                interval:NULL forDate: today];
Run Code Online (Sandbox Code Playgroud)

  • 这个(考虑到mmc的答案)实际上是有效的. (4认同)

mmc*_*mmc 12

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

- (void)setFirstWeekday:(NSUInteger)weekday
Run Code Online (Sandbox Code Playgroud)

应该做的伎俩.


Ami*_*aor 11

在我看来,根据用户区域设置,此设置应该是动态的.因此,应该使用:

NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
[gregorian setLocale:[NSLocale currentLocale]];
Run Code Online (Sandbox Code Playgroud)

这将导致日历根据用户区域设置自动设置第一个工作日.除非您为特定目的/用户区域设置开发应用程序(或者更愿意让用户选择这一天).


Ivo*_*iss 9

我这样做了.

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
Run Code Online (Sandbox Code Playgroud)

  • 你是个天才! (4认同)

Jas*_*ues 8

我在这里遇到了很多问题..也许只是我..

这是一个适合我的答案:

- (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];
}
Run Code Online (Sandbox Code Playgroud)

更新:

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


iwa*_*bed 7

Kris回答的问题是本周初在上个月开始的边缘情况.这是一些更简单的代码,它还检查边缘情况:

// 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];
}
Run Code Online (Sandbox Code Playgroud)

  • 这不适用于一个角落.对于2012-12-31日期,它将返回:2012-01-01 (3认同)