【问题标题】:Strange NSDate and NSDateFormatter behaviour奇怪的 NSDate 和 NSDateFormatter 行为
【发布时间】:2013-05-03 08:07:58
【问题描述】:

我正在尝试获取今年一周的日期。这是我的代码,也是正在计算的运行时值:

为什么年份不正确?也尝试了其他格式,比如 y-w 并且都给了我相同的结果。如果我使用 YYYY-w 但我会得到错误的月份/日期,这个问题会自行解决,因为年份的计算方式不同。仅供参考,这就是我从 YYYY 得到的信息:

现在日期 04-29 是“yyyy”情况下第 18 周的正确日期(请参阅此处:http://www.epochconverter.com/date-and-time/weeknumbers-by-year.php),但只有使用“YYYY”时年份才正确(那么日期是错误的)。

那是怎么回事?

-------- 更新 1 ---------

添加答案之一中提供的解决方案后:

-------- 更新 2 ----------

所以我的日期 2000 与“未定义年份”的值相同(以前是 1970 年)。见这里:http://openradar.appspot.com/12358210

-------- 更新 3 ----------

系统信息(对于那些将尝试复制此信息的人)。

XCode:版本 4.6.2 (4H1003) iOS:6.1 OSX:10.8.3

-------- 更新 4 ----------

iOS 5.1 在使用这个时会提供不同的结果:

好像 iOS 5.1 不支持 NSDateFormatter 中的“w”。

【问题讨论】:

  • 你想得到周数吗?
  • 我有周数。我想通过使用这个 NSDateFormatter 来获得正确的年月日。
  • 使用NSCalender有什么限制吗?
  • 使用 NSCalendar 没有任何限制,但我不想解决这样的问题,我想知道为什么我在这里错了。
  • 当你尝试像 yyyy-w 格式时发生了什么?

标签: iphone ios xcode nsdate nsdateformatter


【解决方案1】:

EDIT 1:这个答案没有解释 OP 看到的结果。有关更多信息,请参阅 cmets 讨论

编辑 2: 我的机器上的结果非常奇特。在 iOS 6 上,星期根本不尊重 System Preferences 中的 first day of week 设置:

iOS 6 总是返回:

2000-1 -> 2000 年 1 月 1 日(星期六)

2001-1 -> 2001 年 1 月 6 日(星期六)

即使我执行[calendar setFirstWeekday: 3][dateFormatter setCalendar: calendar],也完全不会影响结果(与iOS 5 不同)!这肯定是 iOS 6 NSCalendar API 中的一个错误。我建议使用NSDateComponents 或自己计算日期。给出这个答案中的信息应该很容易 - 您可以假设 ISO-8601(第一周至少 4 天,每周从星期一开始),当然,除非您可以询问用户的偏好。


原始答案


这是发生了什么:

在您的语言环境中,一周中的最少天数为 5,并且一周从星期六开始。

假设这是真的,您的第一周将是5th Jan(星期六)-11th Jan 2013。你猜对了,第 18 周就是:4th May 2013

为什么?因为 Apple 关注 Unicode Technical Standard #35 version tr35-25(在 iOS 6+ 上)。

F.4 Week of Year

Values calculated for the Week of Year field range from 1 to 53 for the Gregorian calendar   
(they may have different ranges for other calendars). Week 1 for a year is the first week 
that contains at least the specified minimum number of days from that year. Weeks between 
week 1 of one year and week 1 of the following year are numbered sequentially from 2 to 52 
or 53 (if needed). For example, January 1, 1998 was a Thursday. If the first day of the 
week is MONDAY and the minimum days in a week is 4 (these are the values reflecting ISO 
8601 and many national standards), then week 1 of 1998 starts on December 29, 1997, and 
ends on January 4, 1998. However, if the first day of the week is SUNDAY, then week 1 of 
1998 starts on January 4, 1998, and ends on January 10, 1998. The first three days of 1998 
are then part of week 53 of 1997.

另外,YYYY-w 是正确的格式。


【讨论】:

  • 您的回答正确解释了我在使用第 1 周时得到的结果。YYYY 格式也适用于“周年”,因此这解释了为什么我在 yyyy 的年份变得糟糕,以及为什么我的一周变得糟糕年年。所以问题是这样的:我怎样才能将星期转移到链接中提供的正确星期(发现有问题)?
  • 另外我应该注意的是,运行 iOS 5.1 的模拟器提供了正确的日期与“YYYY-w”,而 iOS 6.1 提供的日期如图 #2 所示。
  • 但是对于 en_US 语言环境,一周的第一天是星期日,而不是星期六,不是吗?
  • @avuthless 你能打印出[[NSCalendar currentCalendar] minimumDaysInFirstWeek][[NSCalendar currentCalendar] firstWeekday]的值来确认吗?
  • @MartinR 是的。日历不仅仅取决于语言环境。尽管即使这样也不能解释为什么 iOS 5.1 会提供与 iOS 6.1 不同的答案。这是 6.1 中的错误吗?
【解决方案2】:

如果您使用的是 NSCalender,那么您将获得像这样的所有组件,

NSDate *date = [NSDate date];
    NSCalendar *calendar = [NSCalendar currentCalendar];
    NSInteger units = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit | NSWeekdayCalendarUnit;
    NSDateComponents *components1 = [calendar components:units fromDate:date];
    NSInteger year = [components1 year];
    NSInteger week=[components1 weekOfYear];

【讨论】:

  • 感谢您的解决方案,但正如我在 cmets 中提到的那样,我并不是在寻找另一种方法来做到这一点。我正在寻找为什么 NSDateFormatter 忽略格式“yyyy-w”的年份输入的答案
【解决方案3】:

你可以试试这个

NSString *dateString = @"2013-18";

NSDateFormatter *dateFormatter = [NSDateFormatter new];
[dateFormatter setDateFormat:@"yyyy-ww"];

NSDate *date = [dateFormatter dateFromString:dateString];
NSLog(@"Date: %@",date);

【讨论】:

  • 用您的解决方案的结果更新了问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多