Cocoa 计算一年中第一周的日期的一周中第一天的日期会更改该月

Cocoa 计算一年中第一周的日期的一周中第一天的日期会更改该月,cocoa,cocoa-touch,nsdate,nscalendar,date-arithmetic,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 = [NSCale

我需要从任何日期获取一周第一天的日期。 这段代码运行得很好,但对于某些日期,我得到了一个非常奇怪的结果。一年中第一周的日期转换为上周的日期:

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

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日可能是次年的第一周。规则是:如果本周的星期四是在十二月,那么这一周属于过去的一年。如果是在一月,这一周就是新年的第一周



每个Mac/iOS开发者都应该观看:WWDC 2011视频

谢谢。我试试看。大约第二部分。正如您在我的示例中所看到的,1月3日是当前2015年53周的一部分。我不明白,这怎么可能…听起来很奇怪,但这是预期的行为。就连苹果公司也两次介入这个问题:一年中的头几天警报不会响。