获取第一个和最后一个工作日。年度第一周和最后一周的奇怪行为

时间:2013-12-18 10:22:21

标签: ios objective-c cocoa-touch nsdate

我想获得给定年份的给定周数(数字)的第一天和最后一天。 我写的函数除了一年的最后一周和第一周外都有效。

例如,如果我要求weekday 1 7 week 1 year 2014 我得到了2015年的第一周!

2014-12-28 // weekday 1
2015-01-03 // weekday 7 

但是应该是正确的结果!

2013-12-29 // weekday 1  
2014-01-04 // weekday 7 

如果我要求2013年第51周,我会正确收到:

2013-12-15 // weekday 1
2013-12-21 // weekday 7

在这里我的功能,我该如何修复这种奇怪的行为?!

// Return the date which is the weekday for a given week number and year
+ (NSDate*)weekDay:(NSInteger)weekday forWeekOfYear:(NSInteger)week year:(NSInteger)year{

    // Date component
    NSDateComponents *comp = [[NSDateComponents alloc]init];
    [comp setWeekOfYear:week];
    [comp setWeekday:weekday];
    [comp setYear:year];

    NSCalendar *calendar = [NSCalendar currentCalendar];
    NSDate *date = [calendar dateFromComponents:comp];

    NSLog(@"week %d year %d weekday %d\n%@", week, year, weekday, date);
    return date;
}

编辑-------------

关注@Guillaume回答我使用setWeekOfYear而不是setYear修改了我的代码。部分工作,我正确地一周的最后一天,但是在第一个工作日,我得到下周的第一天。现在我得到任何周数的错误,不仅是一年的第一个或最后一个。

这是2014年第1周的新结果:

2014-01-05 // weekday1... it should be 2013-12-29. damn!
2014-01-04 // weekday7... it should be 2014-01-04. great! 

就像我用这段代码调用我的类别函数的信息一样:

self.fromDate = [NSDate weekDay:1 forWeekOfYear:self.selectedWeek year:self.selectedYear];
self.toDate = [NSDate weekDay:7 forWeekOfYear:self.selectedWeek year:self.selectedYear];

4 个答案:

答案 0 :(得分:2)

您是否尝试setYearForWeekOfYear:代替setYear:

NSCalendar中,还有一个值得查看的属性minimumDaysInFirstWeek ...

答案 1 :(得分:1)

我得到了这个结果

2013-12-18 14:57:48.090 datecal[20740:303] week 1 year 2014 weekday 1 29/12/2013 00:00:00
2013-12-18 14:57:48.091 datecal[20740:303] week 1 year 2014 weekday 7 04/01/2014 00:00:00

此代码(星期日的第一天):

#import <Foundation/Foundation.h>

@interface NSDate (WeekBoundries)
+ (NSDate*)weekDay:(NSInteger)weekday forWeekOfYear:(NSInteger)week year:(NSInteger)year;
@end

@implementation NSDate (WeekBoundries)
static NSUInteger SUNDAY = 1;
static NSUInteger MONDAY = 2;
static NSUInteger SATURDAY = 7;

+ (NSDate*)weekDay:(NSInteger)weekday forWeekOfYear:(NSInteger)week year:(NSInteger)year{

    // Date component
    NSDateComponents *comp = [[NSDateComponents alloc]init];
    [comp setWeekOfYear:week];
    [comp setWeekday:weekday];
    [comp setYearForWeekOfYear:year];

    NSCalendar *calendar = [NSCalendar currentCalendar];

    calendar.locale = [NSLocale localeWithLocaleIdentifier:@"en_US_POSIX"];
    calendar.firstWeekday = SUNDAY;
    NSDate *date = [calendar dateFromComponents:comp];

    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    [formatter setDateFormat:[NSDateFormatter dateFormatFromTemplate:@"yyyy-MM-dd HH:mm:ss"
                                                             options:0
                                                              locale:[NSLocale currentLocale]]];
    NSLog(@"week %ld year %ld weekday %ld %@", (long)week, (long)year, (long)weekday, [formatter stringFromDate:date]);
    return date;
}

@end


int main(int argc, const char * argv[])
{

    @autoreleasepool {

        NSDate *fromDate = [NSDate weekDay:SUNDAY forWeekOfYear:1 year:2014];
        NSDate *toDate = [NSDate weekDay:SATURDAY forWeekOfYear:1 year:2014];

    }
    return 0;
}

如果您希望星期一是一周的第一天,请更改:

calendar.firstWeekday = SUNDAY;

calendar.firstWeekday = MONDAY;

NSDate *fromDate = [NSDate weekDay:SUNDAY forWeekOfYear:1 year:2014];
NSDate *toDate = [NSDate weekDay:SATURDAY forWeekOfYear:1 year:2014];

NSDate *fromDate = [NSDate weekDay:MONDAY forWeekOfYear:1 year:2014];
NSDate *toDate = [NSDate weekDay:SUNDAY forWeekOfYear:1 year:2014];

如果你把它混在一起

calendar.firstWeekday = MONDAY;
NSDate *fromDate = [NSDate weekDay:SUNDAY forWeekOfYear:1 year:2014];
NSDate *toDate = [NSDate weekDay:SATURDAY forWeekOfYear:1 year:2014];

你会得到你在编辑中描述的行为,因为很明显,你的日历周一作为一周的开始,你会填写一个星期日和星期六。


如果您想尊重用户区域设置,可以执行以下操作:

@interface NSDate (WeekBoundries)
+ (NSDate*)weekDay:(NSInteger)weekday forWeekOfYear:(NSInteger)week year:(NSInteger)year;
@end

@implementation NSDate (WeekBoundries)


+ (NSDate*)weekDay:(NSInteger)weekday forWeekOfYear:(NSInteger)week year:(NSInteger)year{

    NSDateComponents *comp = [[NSDateComponents alloc]init];
    [comp setWeekOfYear:week];
    [comp setWeekday:weekday];
    [comp setYearForWeekOfYear:year];

    NSCalendar *calendar = [NSCalendar currentCalendar];

    NSDate *date = [calendar dateFromComponents:comp];

    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    [formatter setDateFormat:[NSDateFormatter dateFormatFromTemplate:@"yyyy-MM-dd HH:mm:ss"
                                                             options:0
                                                              locale:[NSLocale currentLocale]]];
    NSLog(@"week %ld year %ld weekday %ld %@", (long)week, (long)year, (long)weekday, [formatter stringFromDate:date]);
    return date;
}

@end

-(void)method
{
        static NSUInteger SUNDAY = 1;
        static NSUInteger MONDAY = 2;
        static NSUInteger SATURDAY = 7;

        NSCalendar *calendar = [NSCalendar currentCalendar];

        NSDate *fromDate = [NSDate weekDay:(calendar.firstWeekday == MONDAY)? MONDAY : SUNDAY forWeekOfYear:1 year:2014];
        NSDate *toDate = [NSDate weekDay:(calendar.firstWeekday == MONDAY)? SUNDAY : SATURDAY forWeekOfYear:1 year:2014];
}

答案 2 :(得分:0)

您正在创建错误的日历对象。

通过以下方式创建:

NSCalendar *calendar = [NSCalendar autoupdatingCurrentCalendar];

答案 3 :(得分:-1)

你有没有解决这个问题?

尝试:

int week = 0;
int weekday = 0; 
int year = 2014;
[comp setWeekOfYear:week];
[comp setWeekday:weekday];
[comp setYear:year];

NSCalendar *calendar = [NSCalendar currentCalendar];
NSDate *date = [calendar dateFromComponents:comp];

NSLog(@"week %d year %d weekday %d\n%@", week, year, weekday, date);