NSDateFormatter 报告 2013 年 6 月 2 日为第零周 [英] NSDateFormatter reports June 2, 2013 as being in week zero

查看:56
本文介绍了NSDateFormatter 报告 2013 年 6 月 2 日为第零周的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 NSDateFormatter 将一系列日期转换为一个月内的周数.

我使用的日期格式代码是 yyyyMMW,我读过的所有内容都告诉我 W 将在 1-5 之间.

但是,2013 年 6 月 2 日是星期日(公历中默认的一周开始日),即使正确计算了一周的开始日期,其周数仍报告为 0:

2013-06-03 14:15:45.611 日期=20130531,周=2013055,周开始=201305262013-06-03 14:15:45.612 日期=20130602,周=2013060,周开始=201306022013-06-03 14:15:45.612 日期=20130603,周=2013061,周开始=20130602

一些快速而肮脏的测试代码来重现上面显示的日志:

 NSDateFormatter *dateFormatDaily = [[NSDateFormatter alloc] init];[dateFormatDaily setDateFormat:@"yyyyMMdd"];NSDateFormatter *dateFormatterWeekly = [[NSDateFormatter alloc] init];[dateFormatterWeekly setDateFormat:@"yyyyMMW"];NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];[日历设置FirstWeekday:1];//默认,但为了清楚起见在这里设置NSDateComponents *dateComponents = [[NSDateComponents alloc] init];[dateComponents setMonth:5];[dateComponents setDay:31];[dateComponents setYear:2013];NSDate *date_1 = [日历 dateFromComponents:dateComponents];[dateComponents setMonth:6];[dateComponents setDay:2];NSDate *date_2 = [日历 dateFromComponents:dateComponents];[dateComponents setDay:3];NSDate *date_3 = [日历 dateFromComponents:dateComponents];NSArray *datesToTest = @[date_1, date_2, date_3];for (NSDate *datesToTest 中的日期) {NSString *weekNo = [dateFormatterWeekly stringFromDate:date];NSDate *beginningOfWeek = nil;BOOL rc = [calendar rangeOfUnit:NSWeekCalendarUnit startDate:&beginningOfWeek interval:NULL forDate:date];如果(rc){NSLog(@"date=%@, week=%@, 星期开始=%@", [dateFormatDaily stringFromDate:date], weekNo, [dateFormatDaily stringFromDate:beginningOfWeek]);} 别的 {NSLog(@"无法计算周初");}}

有什么想法吗?在任何情况下,0 的周数似乎对我来说都是错误的.

谢谢

解决方案

导致这种效果的参数有很多.首先,您没有为日期格式化程序设置日历.如果添加

[dateFormatterWeekly setCalendar:calendar];

到您的代码,然后输出将如您所愿:

<前>日期=20130531,周=2013055,周开始=20130526日期=20130602,周=2013062,周开始=20130602日期=20130603,周=2013062,周开始=20130602

但在您的情况下,日期格式化程序使用当前日历,因此具有单独的参数 firstWeekDayminimumDaysInFirstWeek.这些参数取决于语言环境.如果我在区域格式"设置为德语 -> 德国"的 iOS 模拟器上对此进行测试,则

[[dateFormatterWeekly calendar] firstWeekday] = 2[[dateFormatterWeekly calendar] minimumDaysInFirstWeek] = 4

我假设你会有相似的值,因为现在我得到和你一样的输出.

现在对于日期格式化程序,一周从星期一开始,这意味着 6 月 2 日是从 5 月 27 日开始的那一周.这在 6 月算作第 0 周",因为只有本周的某一天是六月,但 minimumDaysInFirstWeek = 4.一个月中的第一周至少有minimumDaysInFirstWeek 天,算作第 1 周".

(我在这里找到了 minimumDaysInFirstWeek 参数的相关性:http://www.cocoabuilder.com/archive/cocoa/326845-week-of-month-confusion.html)

I am using NSDateFormatter to convert a series of dates to a week number within a month.

The date formatting code I am using is yyyyMMW and everything I have read tells me that W will be between 1-5.

But, the 2nd of June 2013 fell on a Sunday (the default start day of the week in the gregorian calendar) and it's week number is reported as 0 even though the start date of the week is calculated correctly:

2013-06-03 14:15:45.611 date=20130531, week=2013055, start of week=20130526
2013-06-03 14:15:45.612 date=20130602, week=2013060, start of week=20130602
2013-06-03 14:15:45.612 date=20130603, week=2013061, start of week=20130602

Some quick and dirty test code to reproduce the log shown above:

    NSDateFormatter *dateFormatDaily = [[NSDateFormatter alloc] init];
[dateFormatDaily setDateFormat:@"yyyyMMdd"];
NSDateFormatter *dateFormatterWeekly = [[NSDateFormatter alloc] init];
[dateFormatterWeekly setDateFormat:@"yyyyMMW"];

NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
[calendar setFirstWeekday:1]; // default but set here for clarity

NSDateComponents *dateComponents = [[NSDateComponents alloc] init];
[dateComponents setMonth:5];
[dateComponents setDay:31];
[dateComponents setYear:2013];
NSDate *date_1 = [calendar dateFromComponents:dateComponents];
[dateComponents setMonth:6];
[dateComponents setDay:2];
NSDate *date_2 = [calendar dateFromComponents:dateComponents];
[dateComponents setDay:3];
NSDate *date_3 = [calendar dateFromComponents:dateComponents];
NSArray *datesToTest = @[date_1, date_2, date_3];

for (NSDate *date in datesToTest) {
    NSString *weekNo = [dateFormatterWeekly stringFromDate:date];
    NSDate *beginningOfWeek = nil;
    BOOL rc = [calendar rangeOfUnit:NSWeekCalendarUnit startDate:&beginningOfWeek interval:NULL forDate:date];
    if (rc) {
        NSLog(@"date=%@, week=%@, start of week=%@", [dateFormatDaily stringFromDate:date], weekNo, [dateFormatDaily stringFromDate:beginningOfWeek]);
    } else {
        NSLog(@"Could not calculate beginning of week");
    }
}

Any ideas? A week number of 0 under any circumstances seems wrong to me.

Thanks

解决方案

There are various parameters that cause this effect. First of all, you did not set a calendar for the date formatter. If you add

[dateFormatterWeekly setCalendar:calendar];

to your code, then the output will be as you expected:

date=20130531, week=2013055, start of week=20130526
date=20130602, week=2013062, start of week=20130602
date=20130603, week=2013062, start of week=20130602

But in your case, the date formatter uses the current calendar, and therefore has separate parameters firstWeekDay and minimumDaysInFirstWeek. These parameters are locale dependent. If I test this on the iOS Simulator with the "Region Format" set to "German -> Germany", then

[[dateFormatterWeekly calendar] firstWeekday]           = 2
[[dateFormatterWeekly calendar] minimumDaysInFirstWeek] = 4

and I assume that you will have similar values, because now I get the same output as you.

Now for the date formatter, the week starts on a Monday, which means that June 2 is in the week starting at May 27. This counts as "week #0" in June, because only one day of this week is in June, but minimumDaysInFirstWeek = 4. The first week in a month that has at least minimumDaysInFirstWeek days, counts as "week #1".

(I found the relevance of the minimumDaysInFirstWeek parameter here: http://www.cocoabuilder.com/archive/cocoa/326845-week-of-month-confusion.html)

这篇关于NSDateFormatter 报告 2013 年 6 月 2 日为第零周的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆