计算一年中第一周中某一天的第一天的日期会更改月份

时间:2015-07-17 15:40:58

标签: cocoa cocoa-touch nsdate nscalendar date-arithmetic

我需要从任何日期获得一周中第一天的日期。 这段代码工作正常,但在某些日期我得到一个非常奇怪的结果。从一年的第一周开始的日期转换为上周的日期:

NSTimeInterval ti = 1420311299;
NSDate* date = [NSDate dateWithTimeIntervalSince1970:ti];

NSLog(@"%@", date); // OUTPUT: 2015-01-03 18:54:59 +0000

NSCalendar* calendar = [NSCalendar currentCalendar];
NSDateComponents *cmps = [calendar components:(kCFCalendarUnitWeekOfYear | kCFCalendarUnitYear) fromDate:date];

cmps.weekday = calendar.firstWeekday;

NSLog(@"%@", cmps); // OUTPUT:  Calendar Year: 2015
                    //          Week of Year: 1
                    //          Weekday: 1



NSDate* newDate = [calendar dateFromComponents:cmps];

NSLog(@"%@", newDate); // OUTPUT: 2015-12-26 22:00:00 +0000

1 个答案:

答案 0 :(得分:2)

NSCalendar类提供了专门的方法来进行这样的计算:

NSDate *date =...;
NSDate *startOfTheWeek;
NSTimeInterval interval;
[[NSCalendar currentCalendar] rangeOfUnit:NSCalendarUnitWeekOfMonth
                                startDate:&startOfTheWeek 
                                 interval:&interval 
                                  forDate:date];

interval包含一周的长度。如果您不需要,可以传递NULL

NSDate *date =...;
NSDate *startOfTheWeek;
[[NSCalendar currentCalendar] rangeOfUnit:NSCalendarUnitWeekOfMonth 
                                startDate:&startOfTheWeek 
                                 interval:NULL
                                  forDate:date];

回答您的原始问题:周'开始和结束与多年不一致'。 1月1日,2日和3日可能是上一年的第53周。 12月29日,30日,31日可能是次年的第一周。规则是:如果本周的星期四是12月,则该星期属于旧年。如果是1月份,那么这一周就是新年的第一周。

每个Mac / iOS开发者都应该观看:WWDC 2011视频"Session 117 - Performing Calendar Calculations"