繁体   English   中英

在Objective-C中获取一年中的第一天

[英]Get first day of week of year in Objective-C

我正在尝试使用DateTools查找星期几,如下所示:

for (NSInteger week = 46; week <= 53; week++) {
    NSDate *tempDate = [NSDate dateWithString:[NSString stringWithFormat:@"2015-%d", (int)week] formatString:@"Y-w"];

    NSLog(@"INFO: tempDate: %@, day: %.2d, week: %d", tempDate, (int)[tempDate day], (int)week);
}

for (NSInteger week = 1; week <= 5; week++) {
    NSDate *tempDate = [NSDate dateWithString:[NSString stringWithFormat:@"2016-%d", (int)week] formatString:@"Y-w"];

    NSLog(@"INFO: tempDate: %@, day: %.2d, week: %d", tempDate, (int)[tempDate day], (int)week);
}

我得到以下输出:

INFO: tempDate: 2015-11-07 22:00:00 +0000, day: 08, week: 46
INFO: tempDate: 2015-11-14 22:00:00 +0000, day: 15, week: 47
INFO: tempDate: 2015-11-21 22:00:00 +0000, day: 22, week: 48
INFO: tempDate: 2015-11-28 22:00:00 +0000, day: 29, week: 49
INFO: tempDate: 2015-12-05 22:00:00 +0000, day: 06, week: 50
INFO: tempDate: 2015-12-12 22:00:00 +0000, day: 13, week: 51
INFO: tempDate: 2015-12-19 22:00:00 +0000, day: 20, week: 52
INFO: tempDate: 2015-12-26 22:00:00 +0000, day: 27, week: 53
INFO: tempDate: 2015-12-26 22:00:00 +0000, day: 27, week: 1
INFO: tempDate: 2016-01-02 22:00:00 +0000, day: 03, week: 2
INFO: tempDate: 2016-01-09 22:00:00 +0000, day: 10, week: 3
INFO: tempDate: 2016-01-16 22:00:00 +0000, day: 17, week: 4
INFO: tempDate: 2016-01-23 22:00:00 +0000, day: 24, week: 5

并且您可以看到, 2015的第53周与2016的第1周具有同一天该网站告诉我2015年有53周)

实际上,从2016开始的第1周从04.01.2016开始。

另外,请注意dateWithString:formatString:给了我一周的第一天的前一天。 这是为什么? 我可以简单地使用dateByAddingDays:1但是我不知道它是否是hackish,应该在其他地方解决该问题。

我尝试使用NSDateComponents作为@DarkDust提到,但无济于事。 所以这:

for (NSInteger week = 1; week <= 5; week++) {
    NSDate *tempDate = [NSDate dateWithString:[NSString stringWithFormat:@"2016-%d", (int)week] formatString:@"Y-w"];

    NSDateComponents *dateComponents = [NSDateComponents new];

    dateComponents.year = 2016;
    dateComponents.weekOfYear = week;

    NSLog(@"INFO: tempDate: %@, day: %.2d, week: %d = %@", tempDate, (int)[tempDate day], (int)week, [calendar dateFromComponents:dateComponents]);
}

给我这个:

INFO: tempDate: 2015-12-26 22:00:00 +0000, day: 27, week: 1 = 2015-12-31 22:00:00 +0000
INFO: tempDate: 2016-01-02 22:00:00 +0000, day: 03, week: 2 = 2015-12-31 22:00:00 +0000
INFO: tempDate: 2016-01-09 22:00:00 +0000, day: 10, week: 3 = 2015-12-31 22:00:00 +0000
INFO: tempDate: 2016-01-16 22:00:00 +0000, day: 17, week: 4 = 2015-12-31 22:00:00 +0000
INFO: tempDate: 2016-01-23 22:00:00 +0000, day: 24, week: 5 = 2015-12-31 22:00:00 +0000

这是DateToolsdateWithString:formatString:实现:

+ (NSDate *)dateWithString:(NSString *)dateString formatString:(NSString *)formatString {

    return [self dateWithString:dateString formatString:formatString timeZone:[NSTimeZone systemTimeZone]];
}

+ (NSDate *)dateWithString:(NSString *)dateString formatString:(NSString *)formatString timeZone:(NSTimeZone *)timeZone {

    static NSDateFormatter *parser = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        parser = [[NSDateFormatter alloc] init];
    });

    parser.dateStyle = NSDateFormatterNoStyle;
    parser.timeStyle = NSDateFormatterNoStyle;
    parser.timeZone = timeZone;
    parser.dateFormat = formatString;

    return [parser dateFromString:dateString];
}

至于重复的报告:

前3名是错误的,其中2名投了反对票,他们甚至根本没有做我需要的事情。

这是一个坏主意,您在做什么。 您必须了解日期是一个时间戳,可以根据所使用的时区和日历对日期进行不同的解释。 正如评论中已经提到的那样,您应该为解决方案使用日期组件。 请注意,打印出日期可能会使用其他格式,并且可能无法预期结果。

一年中的下一个工作日取决于定义。 如果我没记错的话,某些标准(或全部标准)将根据一年中的第一天来处理一年的第一周。 换句话说,如果1.1是星期日,那么一年的第一周是在12月,但是如果是星期二,则是在一月。

因此,如果要查找给定年份的第一个星期一的开始,则代码应如下所示(我没有对其进行测试):

+ (NSDate *)firstWeekInYear:(NSInteger)year {

        NSCalendar *calendar = [NSCalendar autoupdatingCurrentCalendar];

        NSDate *toReturn = nil;
        NSDateComponents *components = [[NSDateComponents alloc] init];
        components.year = year;
        NSDate *beginningOfTheYear = [calendar dateFromComponents:components];
        NSInteger day = [calendar component:NSCalendarUnitWeekday fromDate:beginningOfTheYear];
        NSInteger daysToAdd = (8-day)%7;

        toReturn = [calendar dateByAddingUnit:NSCalendarUnitDay value:daysToAdd toDate:beginningOfTheYear options:kNilOptions];

        return toReturn;
    }

因此,您需要选择日历,使用目标年份创建日期组件,使用日历从这些组件中获取日期以获取年初。 然后找出是哪个工作日,并增加这样的天数,以便结果是一年中第一个星期一的开始。

我终于弄明白了。 @Matic的解决方案在iOS 7中不起作用,很难理解,因此我设法找到了一种在iOS 7上也可以使用的更简单的解决方案:

+ (NSDate *)getFirstDayInWeek:(NSInteger)week ofYear:(NSInteger)year {

    /* create the calendar only once */

    static NSCalendar *calendar = nil;
    static dispatch_once_t onceToken;

    dispatch_once(&onceToken, ^{
        calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];

        calendar.firstWeekday = 2;
        calendar.minimumDaysInFirstWeek = 4;
    });

    NSDateComponents *components = [NSDateComponents new]; // create an empty date components object

    components.year = year;
    components.weekOfYear = week; // set the number of the week in the year
    components.weekday = calendar.firstWeekday; // important! set the result date's day of week

    return [calendar dateFromComponents:components];
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM