Xcode - 设置月中的第几周,然后获取一年中的第几周

Xcode - Set week of month, then get the week of year

目前正在尝试使用 NSDateFormatter 和 NSDateComponents 设置一个月的周数,然后找到一年中的第几周。

假设我们有一个日期:2020 年 5 月 20 日,然后将周数设置为 0、1、2 等。然后从中找出一年中的第几周。

到目前为止,我尝试过使用 NSDateComponents:

NSDate *date = self.date; // 20/05/2020
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *components = [calendar components:NSCalendarUnitMonth | NSCalendarUnitYear fromDate:date];

[components setWeekOfMonth:1];
NSDate *newDate = [calendar dateFromComponents:components];

NSInteger weekOfYear = [calendar components:NSCalendarUnitWeekOfYear fromDate:newDate].weekOfYear;

我总是得到输出 18

预期输出:

Change week of month to: 1 | output: 19 (4th)
Change week of month to: 2 | output: 20 (11th)
Change week of month to: 3 | output: 21 (18th)
Change week of month to: 4 | output: 22 (25th)

问题是在日期组件中设置 setWeekOfMonth 无效。

而是设置 weekdayweekdayOrdinal

NSDate *date = self.date; // 20/05/2020
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *components = [calendar components:NSCalendarUnitMonth | NSCalendarUnitYear fromDate:date];
components.weekday = 2;
components.weekdayOrdinal = 3;
NSDate *newDate = [calendar dateFromComponents:components];

NSInteger weekOfYear = [calendar components:NSCalendarUnitWeekOfYear fromDate:newDate].weekOfYear;

这是一种不同的方法:

它计算当月的第一个星期一,然后枚举下一个星期一直到月底。

- (NSArray *)yearOfWeeksInCurrentMonth
{
    NSCalendar *calendar = [NSCalendar currentCalendar];
    NSDateComponents *components = [calendar components: NSCalendarUnitMonth | NSCalendarUnitYear fromDate:[NSDate date]];
    components.weekday = 2;
    components.weekdayOrdinal = 1;

    NSDate *firstMonday = [calendar dateFromComponents:components];
    NSInteger weekOfYear = [calendar component:NSCalendarUnitWeekOfYear fromDate:firstMonday];

    __block NSMutableArray *result = [NSMutableArray array];
    [result addObject:@[firstMonday, @(weekOfYear)]];
    NSDateComponents *weekComponents = [calendar components: NSCalendarUnitWeekday fromDate:firstMonday];
    [calendar enumerateDatesStartingAfterDate:firstMonday matchingComponents:weekComponents options:NSCalendarMatchNextTime usingBlock:^(NSDate * _Nullable date, BOOL exactMatch, BOOL * _Nonnull stop) {
        if (date != nil) {
            if ( [calendar component:NSCalendarUnitMonth fromDate:date] > components.month ) {
                *stop = YES;
            } else {
                NSInteger weekOfYear = [calendar component:NSCalendarUnitWeekOfYear fromDate:date];
                [result addObject:@[date, @(weekOfYear)]];
            }
        }
    }];
    return [result copy];
}

return值是一个包含日期(NSDate)和对应的weekOfYear(NSNumber)的数组

(
        (
        "2020-05-03 22:00:00 +0000",
        19
    ),
        (
        "2020-05-10 22:00:00 +0000",
        20
    ),
        (
        "2020-05-17 22:00:00 +0000",
        21
    ),
        (
        "2020-05-24 22:00:00 +0000",
        22
    )
)