5

我正在创建各种日历控件...

我需要知道的一件事是一个月有多少周......

所以NSCalendar rangeOfUnit:inUnit:forDate似乎正是我需要的......

除了我注意到一些看起来不对劲的东西,我不太明白为什么会这样......

以下代码...

NSCalendar *calendar = [NSCalendar currentCalendar];

NSDateComponents *dateComponents = [[NSDateComponents alloc] init];
[dateComponents setYear: 2010];
[dateComponents setDay: 1];

for (int x=1; x<=12; x++)
{
    [dateComponents setMonth: x];

    NSDate *date = [calendar dateFromComponents:dateComponents];
    NSLog(@"Date: %@", date);

    NSRange range = [calendar rangeOfUnit: NSWeekCalendarUnit
                                   inUnit: NSMonthCalendarUnit
                                  forDate:date];

    NSLog(@"%d Weeks in Month %d", range.length, [dateComponents month]);

}

正在返回以下调试消息...

2010-03-14 13:08:10.350 Scrap[4256:207] Date: 2010-01-01 00:00:00 -0500
2010-03-14 13:08:10.351 Scrap[4256:207] 5 Weeks in Month 1
2010-03-14 13:08:10.352 Scrap[4256:207] Date: 2010-02-01 00:00:00 -0500
2010-03-14 13:08:10.352 Scrap[4256:207] 4 Weeks in Month 2
2010-03-14 13:08:10.353 Scrap[4256:207] Date: 2010-03-01 00:00:00 -0500
2010-03-14 13:08:10.353 Scrap[4256:207] 5 Weeks in Month 3
2010-03-14 13:08:10.354 Scrap[4256:207] Date: 2010-04-01 00:00:00 -0400
2010-03-14 13:08:10.355 Scrap[4256:207] 5 Weeks in Month 4
2010-03-14 13:08:10.356 Scrap[4256:207] Date: 2010-05-01 00:00:00 -0400
2010-03-14 13:08:10.357 Scrap[4256:207] 5 Weeks in Month 5
2010-03-14 13:08:10.358 Scrap[4256:207] Date: 2010-06-01 00:00:00 -0400
2010-03-14 13:08:10.358 Scrap[4256:207] 5 Weeks in Month 6
2010-03-14 13:08:10.359 Scrap[4256:207] Date: 2010-07-01 00:00:00 -0400
2010-03-14 13:08:10.360 Scrap[4256:207] 5 Weeks in Month 7
2010-03-14 13:08:10.361 Scrap[4256:207] Date: 2010-08-01 00:00:00 -0400
2010-03-14 13:08:10.364 Scrap[4256:207] 5 Weeks in Month 8
2010-03-14 13:08:10.364 Scrap[4256:207] Date: 2010-09-01 00:00:00 -0400
2010-03-14 13:08:10.365 Scrap[4256:207] 5 Weeks in Month 9
2010-03-14 13:08:10.366 Scrap[4256:207] Date: 2010-10-01 00:00:00 -0400
2010-03-14 13:08:10.366 Scrap[4256:207] 5 Weeks in Month 10
2010-03-14 13:08:10.367 Scrap[4256:207] Date: 2010-11-01 00:00:00 -0400
2010-03-14 13:08:10.367 Scrap[4256:207] 5 Weeks in Month 11
2010-03-14 13:08:10.369 Scrap[4256:207] Date: 2010-12-01 00:00:00 -0500
2010-03-14 13:08:10.369 Scrap[4256:207] 52 Weeks in Month 12

我不太明白为什么我在第 12 个月有 52 周。

有什么线索吗?

2010 年 3 月 20 日编辑:

看看我如何不能rangeOfUnit:inUnit:forDate用来计算一个月的周数。我决定找出一种不同的方法来计算相同的值。

我认为我应该以非公历本地化方式执行此操作,因此我尝试从获取一周中的天数开始,但我得到了一周中 28 天的结果。所以我开始编写更多代码来找出原因......

我想确保我正在使用的 NSCalendar 类型实际上是我应该得到的......这让我发现了一些不同......

NSCalendar *currentCalendar = [NSCalendar currentCalendar];

NSLog(@"Calendar with 'currentCalendar' Identifier: %@", 
      [currentCalendar calendarIdentifier]);

NSCalendar *calendarWithIdentifier = [[[NSCalendar alloc] initWithCalendarIdentifier: NSGregorianCalendar] autorelease];

NSLog(@"Calendar created with identifier Identifier: %@", 
      [calendarWithIdentifier calendarIdentifier]);

NSDate *now = [[NSDate alloc] init];

NSDateComponents *currentMonth = [currentCalendar components: NSMonthCalendarUnit | NSYearCalendarUnit
                                                    fromDate: now];

NSDate *currentMonthDate = [currentCalendar dateFromComponents: currentMonth];

NSRange daysInWeekRange = [currentCalendar rangeOfUnit: NSDayCalendarUnit
                                                inUnit: NSWeekCalendarUnit
                                               forDate: currentMonthDate];

NSLog(@"CurrentCalendar: Length:%u Location:%u", daysInWeekRange.length, daysInWeekRange.location);

currentMonth = [calendarWithIdentifier components: NSMonthCalendarUnit | NSYearCalendarUnit 
                                         fromDate: now];

currentMonthDate = [calendarWithIdentifier dateFromComponents: currentMonth];

daysInWeekRange = [calendarWithIdentifier rangeOfUnit: NSDayCalendarUnit
                                               inUnit: NSWeekCalendarUnit
                                              forDate: currentMonthDate];

NSLog(@"GregorianCalendar: Length:%u Location:%u", daysInWeekRange.length, daysInWeekRange.location);

这让我得到了以下日志结果......

2010-03-20 21:02:27.245 Scrap[52189:207] Calendar with 'currentCalendar' Identifier: gregorian
2010-03-20 21:02:27.246 Scrap[52189:207] Calendar created with identifier Identifier: gregorian
2010-03-20 21:02:27.248 Scrap[52189:207] CurrentCalendar: Length:28 Location:1
2010-03-20 21:02:27.249 Scrap[52189:207] GregorianCalendar: Length:7 Location:1

根据@CarlNorum 的经验,我将代码片段编译为 10.6 Cocoa 应用程序,我得到以下...

2010-03-20 21:05:35.636 ScrapCocoa[52238:a0f] Calendar with 'currentCalendar' Identifier: gregorian
2010-03-20 21:05:35.636 ScrapCocoa[52238:a0f] Calendar created with identifier Identifier: gregorian
2010-03-20 21:05:35.637 ScrapCocoa[52238:a0f] CurrentCalendar: Length:6 Location:1
2010-03-20 21:05:35.638 ScrapCocoa[52238:a0f] GregorianCalendar: Length:7 Location:1

我看到了希望,将 NSCalendar 实例显式创建为公历会导致我原来的问题得到更好的结果......所以我修改了原来的代码

NSCalendar *currentCalendar = [NSCalendar currentCalendar];

NSLog(@"Calendar with 'currentCalendar' Identifier: %@", 
      [currentCalendar calendarIdentifier]);

NSCalendar *calendarWithIdentifier = [[[NSCalendar alloc] initWithCalendarIdentifier: NSGregorianCalendar] autorelease];

NSLog(@"Calendar created with identifier Identifier: %@", 
      [calendarWithIdentifier calendarIdentifier]);

NSDateComponents *dateComponents = [[[NSDateComponents alloc] init] autorelease];
[dateComponents setYear: 2010];
[dateComponents setDay: 1];

for (int x=1; x<=12; x++)
{
    [dateComponents setMonth: x];

    NSDate *date = [currentCalendar dateFromComponents: dateComponents];
    NSRange range = [currentCalendar rangeOfUnit: NSWeekCalendarUnit
                                          inUnit: NSMonthCalendarUnit
                                         forDate: date];

    NSLog(@"CurrentCalendar Date: %@", date);
    NSLog(@"CurrentCalendar: %d Weeks in Month %d", range.length, [dateComponents month]);

    date = [calendarWithIdentifier dateFromComponents: dateComponents];

    range = [calendarWithIdentifier rangeOfUnit: NSWeekCalendarUnit
                                         inUnit: NSMonthCalendarUnit
                                        forDate: date];

    NSLog(@"GregorianCalendar Date: %@", date);
    NSLog(@"GregorianCalendar: %d Weeks in Month %d", range.length, [dateComponents month]);

}

不幸的是,使用以这种方式创建的日历并没有返回不同的结果。

2010-03-20 21:15:40.465 Scrap[52367:207] Calendar with 'currentCalendar' Identifier: gregorian
2010-03-20 21:15:40.466 Scrap[52367:207] Calendar created with identifier Identifier: gregorian
2010-03-20 21:15:40.468 Scrap[52367:207] CurrentCalendar Date: 2010-01-01 00:00:00 -0500
2010-03-20 21:15:40.468 Scrap[52367:207] CurrentCalendar: 5 Weeks in Month 1
2010-03-20 21:15:40.469 Scrap[52367:207] GregorianCalendar Date: 2010-01-01 00:00:00 -0500
2010-03-20 21:15:40.470 Scrap[52367:207] GregorianCalendar: 5 Weeks in Month 1
2010-03-20 21:15:40.471 Scrap[52367:207] CurrentCalendar Date: 2010-02-01 00:00:00 -0500
2010-03-20 21:15:40.471 Scrap[52367:207] CurrentCalendar: 4 Weeks in Month 2
2010-03-20 21:15:40.472 Scrap[52367:207] GregorianCalendar Date: 2010-02-01 00:00:00 -0500
2010-03-20 21:15:40.473 Scrap[52367:207] GregorianCalendar: 4 Weeks in Month 2
2010-03-20 21:15:40.473 Scrap[52367:207] CurrentCalendar Date: 2010-03-01 00:00:00 -0500
2010-03-20 21:15:40.474 Scrap[52367:207] CurrentCalendar: 5 Weeks in Month 3
2010-03-20 21:15:40.475 Scrap[52367:207] GregorianCalendar Date: 2010-03-01 00:00:00 -0500
2010-03-20 21:15:40.475 Scrap[52367:207] GregorianCalendar: 5 Weeks in Month 3
2010-03-20 21:15:40.476 Scrap[52367:207] CurrentCalendar Date: 2010-04-01 00:00:00 -0400
2010-03-20 21:15:40.477 Scrap[52367:207] CurrentCalendar: 5 Weeks in Month 4
2010-03-20 21:15:40.478 Scrap[52367:207] GregorianCalendar Date: 2010-04-01 00:00:00 -0400
2010-03-20 21:15:40.479 Scrap[52367:207] GregorianCalendar: 5 Weeks in Month 4
2010-03-20 21:15:40.480 Scrap[52367:207] CurrentCalendar Date: 2010-05-01 00:00:00 -0400
2010-03-20 21:15:40.480 Scrap[52367:207] CurrentCalendar: 5 Weeks in Month 5
2010-03-20 21:15:40.482 Scrap[52367:207] GregorianCalendar Date: 2010-05-01 00:00:00 -0400
2010-03-20 21:15:40.482 Scrap[52367:207] GregorianCalendar: 5 Weeks in Month 5
2010-03-20 21:15:40.483 Scrap[52367:207] CurrentCalendar Date: 2010-06-01 00:00:00 -0400
2010-03-20 21:15:40.483 Scrap[52367:207] CurrentCalendar: 5 Weeks in Month 6
2010-03-20 21:15:40.484 Scrap[52367:207] GregorianCalendar Date: 2010-06-01 00:00:00 -0400
2010-03-20 21:15:40.485 Scrap[52367:207] GregorianCalendar: 5 Weeks in Month 6
2010-03-20 21:15:40.485 Scrap[52367:207] CurrentCalendar Date: 2010-07-01 00:00:00 -0400
2010-03-20 21:15:40.486 Scrap[52367:207] CurrentCalendar: 5 Weeks in Month 7
2010-03-20 21:15:40.486 Scrap[52367:207] GregorianCalendar Date: 2010-07-01 00:00:00 -0400
2010-03-20 21:15:40.487 Scrap[52367:207] GregorianCalendar: 5 Weeks in Month 7
2010-03-20 21:15:40.488 Scrap[52367:207] CurrentCalendar Date: 2010-08-01 00:00:00 -0400
2010-03-20 21:15:40.488 Scrap[52367:207] CurrentCalendar: 5 Weeks in Month 8
2010-03-20 21:15:40.489 Scrap[52367:207] GregorianCalendar Date: 2010-08-01 00:00:00 -0400
2010-03-20 21:15:40.489 Scrap[52367:207] GregorianCalendar: 5 Weeks in Month 8
2010-03-20 21:15:40.490 Scrap[52367:207] CurrentCalendar Date: 2010-09-01 00:00:00 -0400
2010-03-20 21:15:40.491 Scrap[52367:207] CurrentCalendar: 5 Weeks in Month 9
2010-03-20 21:15:40.491 Scrap[52367:207] GregorianCalendar Date: 2010-09-01 00:00:00 -0400
2010-03-20 21:15:40.492 Scrap[52367:207] GregorianCalendar: 5 Weeks in Month 9
2010-03-20 21:15:40.493 Scrap[52367:207] CurrentCalendar Date: 2010-10-01 00:00:00 -0400
2010-03-20 21:15:40.493 Scrap[52367:207] CurrentCalendar: 5 Weeks in Month 10
2010-03-20 21:15:40.494 Scrap[52367:207] GregorianCalendar Date: 2010-10-01 00:00:00 -0400
2010-03-20 21:15:40.494 Scrap[52367:207] GregorianCalendar: 5 Weeks in Month 10
2010-03-20 21:15:40.495 Scrap[52367:207] CurrentCalendar Date: 2010-11-01 00:00:00 -0400
2010-03-20 21:15:40.496 Scrap[52367:207] CurrentCalendar: 5 Weeks in Month 11
2010-03-20 21:15:40.496 Scrap[52367:207] GregorianCalendar Date: 2010-11-01 00:00:00 -0400
2010-03-20 21:15:40.497 Scrap[52367:207] GregorianCalendar: 5 Weeks in Month 11
2010-03-20 21:15:40.498 Scrap[52367:207] CurrentCalendar Date: 2010-12-01 00:00:00 -0500
2010-03-20 21:15:40.498 Scrap[52367:207] CurrentCalendar: 52 Weeks in Month 12
2010-03-20 21:15:40.499 Scrap[52367:207] GregorianCalendar Date: 2010-12-01 00:00:00 -0500
2010-03-20 21:15:40.500 Scrap[52367:207] GregorianCalendar: 52 Weeks in Month 12

为 Cocoa 编译代码只是为了好玩,实际上很有趣……因为结果真的很不一样

2010-03-20 21:11:24.610 ScrapCocoa[52313:a0f] Calendar with 'currentCalendar' Identifier: gregorian
2010-03-20 21:11:24.611 ScrapCocoa[52313:a0f] Calendar created with identifier Identifier: gregorian
2010-03-20 21:11:24.613 ScrapCocoa[52313:a0f] CurrentCalendar Date: 2010-01-01 00:00:00 -0500
2010-03-20 21:11:24.613 ScrapCocoa[52313:a0f] CurrentCalendar: 6 Weeks in Month 1
2010-03-20 21:11:24.614 ScrapCocoa[52313:a0f] GregorianCalendar Date: 2010-01-01 00:00:00 -0500
2010-03-20 21:11:24.615 ScrapCocoa[52313:a0f] GregorianCalendar: 5 Weeks in Month 1
2010-03-20 21:11:24.616 ScrapCocoa[52313:a0f] CurrentCalendar Date: 2010-02-01 00:00:00 -0500
2010-03-20 21:11:24.616 ScrapCocoa[52313:a0f] CurrentCalendar: 5 Weeks in Month 2
2010-03-20 21:11:24.617 ScrapCocoa[52313:a0f] GregorianCalendar Date: 2010-02-01 00:00:00 -0500
2010-03-20 21:11:24.618 ScrapCocoa[52313:a0f] GregorianCalendar: 4 Weeks in Month 2
2010-03-20 21:11:24.619 ScrapCocoa[52313:a0f] CurrentCalendar Date: 2010-03-01 00:00:00 -0500
2010-03-20 21:11:24.619 ScrapCocoa[52313:a0f] CurrentCalendar: 5 Weeks in Month 3
2010-03-20 21:11:24.620 ScrapCocoa[52313:a0f] GregorianCalendar Date: 2010-03-01 00:00:00 -0500
2010-03-20 21:11:24.621 ScrapCocoa[52313:a0f] GregorianCalendar: 5 Weeks in Month 3
2010-03-20 21:11:24.622 ScrapCocoa[52313:a0f] CurrentCalendar Date: 2010-04-01 00:00:00 -0400
2010-03-20 21:11:24.622 ScrapCocoa[52313:a0f] CurrentCalendar: 5 Weeks in Month 4
2010-03-20 21:11:24.623 ScrapCocoa[52313:a0f] GregorianCalendar Date: 2010-04-01 00:00:00 -0400
2010-03-20 21:11:24.623 ScrapCocoa[52313:a0f] GregorianCalendar: 5 Weeks in Month 4
2010-03-20 21:11:24.624 ScrapCocoa[52313:a0f] CurrentCalendar Date: 2010-05-01 00:00:00 -0400
2010-03-20 21:11:24.625 ScrapCocoa[52313:a0f] CurrentCalendar: 6 Weeks in Month 5
2010-03-20 21:11:24.625 ScrapCocoa[52313:a0f] GregorianCalendar Date: 2010-05-01 00:00:00 -0400
2010-03-20 21:11:24.626 ScrapCocoa[52313:a0f] GregorianCalendar: 6 Weeks in Month 5
2010-03-20 21:11:24.627 ScrapCocoa[52313:a0f] CurrentCalendar Date: 2010-06-01 00:00:00 -0400
2010-03-20 21:11:24.627 ScrapCocoa[52313:a0f] CurrentCalendar: 5 Weeks in Month 6
2010-03-20 21:11:24.628 ScrapCocoa[52313:a0f] GregorianCalendar Date: 2010-06-01 00:00:00 -0400
2010-03-20 21:11:24.628 ScrapCocoa[52313:a0f] GregorianCalendar: 5 Weeks in Month 6
2010-03-20 21:11:24.629 ScrapCocoa[52313:a0f] CurrentCalendar Date: 2010-07-01 00:00:00 -0400
2010-03-20 21:11:24.630 ScrapCocoa[52313:a0f] CurrentCalendar: 5 Weeks in Month 7
2010-03-20 21:11:24.630 ScrapCocoa[52313:a0f] GregorianCalendar Date: 2010-07-01 00:00:00 -0400
2010-03-20 21:11:24.631 ScrapCocoa[52313:a0f] GregorianCalendar: 5 Weeks in Month 7
2010-03-20 21:11:24.632 ScrapCocoa[52313:a0f] CurrentCalendar Date: 2010-08-01 00:00:00 -0400
2010-03-20 21:11:24.632 ScrapCocoa[52313:a0f] CurrentCalendar: 5 Weeks in Month 8
2010-03-20 21:11:24.633 ScrapCocoa[52313:a0f] GregorianCalendar Date: 2010-08-01 00:00:00 -0400
2010-03-20 21:11:24.633 ScrapCocoa[52313:a0f] GregorianCalendar: 6 Weeks in Month 8
2010-03-20 21:11:24.634 ScrapCocoa[52313:a0f] CurrentCalendar Date: 2010-09-01 00:00:00 -0400
2010-03-20 21:11:24.635 ScrapCocoa[52313:a0f] CurrentCalendar: 5 Weeks in Month 9
2010-03-20 21:11:24.636 ScrapCocoa[52313:a0f] GregorianCalendar Date: 2010-09-01 00:00:00 -0400
2010-03-20 21:11:24.636 ScrapCocoa[52313:a0f] GregorianCalendar: 5 Weeks in Month 9
2010-03-20 21:11:24.637 ScrapCocoa[52313:a0f] CurrentCalendar Date: 2010-10-01 00:00:00 -0400
2010-03-20 21:11:24.637 ScrapCocoa[52313:a0f] CurrentCalendar: 6 Weeks in Month 10
2010-03-20 21:11:24.638 ScrapCocoa[52313:a0f] GregorianCalendar Date: 2010-10-01 00:00:00 -0400
2010-03-20 21:11:24.639 ScrapCocoa[52313:a0f] GregorianCalendar: 5 Weeks in Month 10
2010-03-20 21:11:24.640 ScrapCocoa[52313:a0f] CurrentCalendar Date: 2010-11-01 00:00:00 -0400
2010-03-20 21:11:24.640 ScrapCocoa[52313:a0f] CurrentCalendar: 5 Weeks in Month 11
2010-03-20 21:11:24.641 ScrapCocoa[52313:a0f] GregorianCalendar Date: 2010-11-01 00:00:00 -0400
2010-03-20 21:11:24.641 ScrapCocoa[52313:a0f] GregorianCalendar: 5 Weeks in Month 11
2010-03-20 21:11:24.642 ScrapCocoa[52313:a0f] CurrentCalendar Date: 2010-12-01 00:00:00 -0500
2010-03-20 21:11:24.642 ScrapCocoa[52313:a0f] CurrentCalendar: 5 Weeks in Month 12
2010-03-20 21:11:24.643 ScrapCocoa[52313:a0f] GregorianCalendar Date: 2010-12-01 00:00:00 -0500
2010-03-20 21:11:24.644 ScrapCocoa[52313:a0f] GregorianCalendar: 5 Weeks in Month 12

我想这是我放弃的时候...

4

1 回答 1

2

使用 10.6 SDK 尝试了此代码,它似乎可以工作。

2010-03-14 19:11:49.424 无标题[61397:a0f] 日期:2010-01-01 00:00:00 -0500
2010-03-14 19:11:49.425 无标题[61397:a0f] 第 1 个月的 6 周
2010-03-14 19:11:49.426 无标题[61397:a0f] 日期:2010-02-01 00:00:00 -0500
2010-03-14 19:11:49.427 无标题[61397:a0f] 第 2 个月的 5 周
2010-03-14 19:11:49.428 无标题[61397:a0f] 日期:2010-03-01 00:00:00 -0500
2010-03-14 19:11:49.429 无标题[61397:a0f] 第 3 个月的 5 周
2010-03-14 19:11:49.429 无标题[61397:a0f] 日期:2010-04-01 00:00:00 -0400
2010-03-14 19:11:49.430 无标题[61397:a0f] 第 4 个月的 5 周
2010-03-14 19:11:49.431 无标题[61397:a0f] 日期:2010-05-01 00:00:00 -0400
2010-03-14 19:11:49.431 无标题[61397:a0f] 第 5 个月的 6 周
2010-03-14 19:11:49.432 无标题[61397:a0f] 日期:2010-06-01 00:00:00 -0400
2010-03-14 19:11:49.433 无标题[61397:a0f] 第 6 个月的 5 周
2010-03-14 19:11:49.434 无标题[61397:a0f] 日期:2010-07-01 00:00:00 -0400
2010-03-14 19:11:49.434 无标题[61397:a0f] 第 7 个月的 5 周
2010-03-14 19:11:49.435 无标题[61397:a0f] 日期:2010-08-01 00:00:00 -0400
2010-03-14 19:11:49.436 无标题[61397:a0f] 第 8 个月的 5 周
2010-03-14 19:11:49.437 无标题[61397:a0f] 日期:2010-09-01 00:00:00 -0400
2010-03-14 19:11:49.437 无标题[61397:a0f] 第 9 个月的 5 周
2010-03-14 19:11:49.438 无标题[61397:a0f] 日期:2010-10-01 00:00:00 -0400
2010-03-14 19:11:49.439 无标题[61397:a0f] 第 10 个月的 6 周
2010-03-14 19:11:49.439 无标题[61397:a0f] 日期:2010-11-01 00:00:00 -0400
2010-03-14 19:11:49.440 无标题[61397:a0f] 第 11 个月的 5 周
2010-03-14 19:11:49.441 无标题[61397:a0f] 日期:2010-12-01 00:00:00 -0500
2010-03-14 19:11:49.441 无标题[61397:a0f] 第 12 个月的 5 周

我用 iPhone SDK 试过了,我得到了和你一样的输出。目前尚不清楚 iPhone SDK 是否也在其他许多月份输出正确的值。例如,我同意 Jan. 有 6 周的 10.6 SDK 答案。

我看不出您的代码有任何明显错误。

我可能首先建议前往http://bugreport.apple.com并提交错误。

您也可以前往 Apple 的私人开发者论坛 ( http://developer.apple.com/devforums/ ) 并尝试在那里提问。

当然,您也可以向 Apple (dts@apple.com - http://developer.apple.com/programs/adcbenefits/ ) 提交技术支持事件...如果您的 ADC 帐户中没有任何支持,我相信苹果会很乐意卖给你一个,你可以直接与苹果工程师讨论这个问题。

于 2010-03-14T23:19:49.380 回答