Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NSCalendar dateFromComponents returns wrong date by 2

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?

like image 201
Stefan Projchev Avatar asked Oct 05 '22 21:10

Stefan Projchev


1 Answers

(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".

like image 139
Jon Skeet Avatar answered Oct 13 '22 10:10

Jon Skeet