【问题标题】:NSCalendar dateFromComponents returns wrong date by 2NSCalendar dateFromComponents 返回错误的日期 2
【发布时间】:2013-02-14 17:14:27
【问题描述】:

我想知道一年中第一周的日期:

NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *components = [[NSDateComponents alloc] init];
[components setYear:2013];
[components setMonth:1];
[components setWeekOfMonth:1];
[components setWeekday:1];
NSDate *newDate = [calendar dateFromComponents:components];
NSLog(@"%@",newDate);

我得到的是:

2012-12-29 23:00:00 +0000

当我与我的 mac 日历进行比较时,我需要得到的是:

2012-12-31 23:00:00 +0000

有什么建议吗?

【问题讨论】:

    标签: ios calendar components nsdate nsdatecomponents


    【解决方案1】:

    (我知道你现在已经弄清楚发生了什么,但为了未来的读者......)

    看看你在这里做什么:

    NSDateComponents *components = [[NSDateComponents alloc] init];
    [components setYear:2013];
    [components setMonth:1];
    [components setWeekOfMonth:1];
    [components setWeekday:1];
    

    让我们以今天(2013 年 2 月 28 日)为例,看看我们在每一步之后得到了什么(假设;我无法检查这个!):

    • setYear:2013 - 没有变化,因为已经是 2013 年了
    • setMonth:1 - 更改为 1 月:2013-01-28
    • setWeekOfMonth:1 - 在 2013 年 1 月的第一周更改为同一天(星期四):2013-01-03
    • setWeekday:1 - 改成同一周的星期日:2012-12-30

    现在,当您打印出 2012 年 12 月 30 日的当地午夜,但在 UTC 中,您会得到“2012 年 12 月 29 日 23:00:00 +0000”,因为您的当地时区可能提前 1 小时UTC。

    因此,正如您已经确定的那样,您需要 setDay 而不是 setWeekOfMonth / setWeekday,假设您真的想要“1 月 1 日”而不是“1 月第 1 周的星期日”。

    【讨论】:

      【解决方案2】:

      问题可能是设置weekDay 这是工作代码

       NSCalendar *calendar = [NSCalendar currentCalendar];
          NSDateComponents *components = [[NSDateComponents alloc] init];
          [components setYear:2013];
          [components setMonth:1];
          [components setDay:1];
      
          NSDate *newDate = [calendar dateFromComponents:components];
          NSLog(@"%@",newDate); //2012-12-31 23:00:00 +0000
      

      您可以使用NSGregorianCalendar 代替currentCalender 的其他替代方式

      NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
              NSDateComponents *comp = [gregorian components:(NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit) fromDate:[NSDate date]];
      [comp setYear:2013];
      [comp setMonth:1];
      [comp setDay:1];
      NSDate *firstDayOfMonthDate = [gregorian dateFromComponents:comp];
      NSLog(@"%@",firstDayOfMonthDate);  // 2012-12-31 23:00:00 +0000
      

      【讨论】:

      • 很好,如果对您有帮助,您可以接受答案,其次我已经编辑了输出的答案
      • 问题不在于使用 NSGregorianCalendar 而不是特别是 currentCalendar - 它是 setDay 与 setWeekday;你的代码 is 在这方面发生了变化,但你没有在文本中提到这一点。我建议您编辑以解释之前发生的事情。
      • @nsgulliver:好的,但 NSGregorianCalendar 并不是真正的替代 - 你仍然需要使用setDay。我添加了一个答案,解释了我认为原始代码中发生的事情。
      • @JonSkeet date 即使您没有设置日期也会显示预期结果
      • @nsgulliver:绝对值得保留 :)
      猜你喜欢
      • 1970-01-01
      • 2011-05-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多