5

I want to find out the date of the first week of a mouth in a year:

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);

What I get is:

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

And when I compare to my mac calendar what I need to get is:

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

Any suggestions?

Dilip Manek
  • 9,095
  • 5
  • 44
  • 56

2 Answers2

4

(I realize you've now worked out what was going on, but for the sake of future readers...)

Look at what you're doing here:

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

Let's take today (28th February 2013) as an example and see what we get after each step (hypothetically; I can't check this!):

  • setYear:2013 - no change, as the year is already 2013
  • setMonth:1 - change to January: 2013-01-28
  • setWeekOfMonth:1 - change to the same day-of-week (Thursday) in the first week of January 2013: 2013-01-03
  • setWeekday:1 - change to the Sunday in the same week: 2012-12-30

Now when you print out the local midnight of 2012-12-30, but in UTC, you're getting "2012-12-29 23:00:00 +0000" as presumably your local time zone is 1 hour ahead of UTC.

So as you've already established, you want setDay instead of setWeekOfMonth / setWeekday, assuming you really want "January 1st" rather than "the Sunday of week 1 of January".

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
0

Problem might be setting the weekDay here is the working code

 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

other alternate you could use NSGregorianCalendar, instead of 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
nsgulliver
  • 12,655
  • 23
  • 43
  • 64
  • good you could accept answer if it helps you, secondly i have edited answer for the output – nsgulliver Feb 28 '13 at 13:48
  • The problem isn't using NSGregorianCalendar instead of currentCalendar in particular - it's setDay vs setWeekday; your code *is* changed in that respect, but you don't mention that in the text. I suggest you edit to explain what was going on before. – Jon Skeet Feb 28 '13 at 13:53
  • @nsgulliver: Okay, but it's not really that NSGregorianCalendar is an *alternative* - you still need to use `setDay`. I've added an answer explaining what I believe is going on in the original code. – Jon Skeet Feb 28 '13 at 14:01
  • @JonSkeet date will show the expected results even you don't set the day – nsgulliver Feb 28 '13 at 14:05
  • @nsgulliver: What, if you *just* set the year and month? Does that just automatically set it to day 1? Ick. (I'd still use `setDay` anyway, as that's clearer.) Or are you talking about only in the case where you explicitly initialize the calendar? It's not very clear. – Jon Skeet Feb 28 '13 at 14:09
  • As my answer was not very comprehensive and you have elaborated quite good so i +1 your answer, but leave my answer for anyone needing to use the code – nsgulliver Feb 28 '13 at 14:13
  • 1
    @nsgulliver: Definitely - it's worth keeping :) – Jon Skeet Feb 28 '13 at 14:21