43

I'm trying to generate a NSDate from a month day and year (all in integer format).

Right now my attempt is such:

NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *components = [[NSDateComponents alloc] init];
NSNumber *day = [dataSource valueForKey:@"day"];
NSNumber *month = [dataSource valueForKey:@"month"];
NSNumber *year = [dataSource valueForKey:@"year"];
[components setDay:[day intValue]];
[components setMonth:[month intValue]];
[components setMonth:[year intValue]];
NSDate *_date = [calendar dateFromComponents:components];

However, _date outputs the following when day = 24, month = 8, year = 2011:

0168-07-25 04:56:02 +0000

I must be doing something horribly wrong, but I have no idea what. Anyone know what might be going on?

Russia Must Remove Putin
  • 374,368
  • 89
  • 403
  • 331
minimalpop
  • 6,997
  • 13
  • 68
  • 80
  • 1
    Came here at the end of 2016 and this question is still helpful. Given that there are 30 helpful votes on this, I would vote to re-open if possible. Additionally, none of the close voters have objective-c, iOS, cocoa-touch, cocoa, nsdate in their top tags looking at their profiles. – C. Tewalt Dec 13 '16 at 22:19

4 Answers4

43

You have a typo in your code: (last line should be setYear:)

 [components setDay:[day intValue]];
 [components setMonth:[month intValue]];
 [components setYear:[year intValue]];
Christopher A
  • 2,961
  • 1
  • 22
  • 23
  • Yep, when you divide things out it ALMOST works out -- Not clear why the year is 168 vs 167, though, or why the day is 25 vs 24. But the poor NSDateComponents object was no doubt sorely confused. – Hot Licks Oct 05 '11 at 17:20
  • (The day is likely off due to a failure to set timeZone to GMT.) – Hot Licks Oct 05 '11 at 17:23
  • 3
    Thanks! Definitely needed another set of eyes (or another pot of coffee):) – minimalpop Oct 05 '11 at 17:23
  • The date is off because things get weird when you use ancient years. There's been many subtle corrections throughout the use of calendars which have been accommodated for in Apple's framework. Take a look [here](https://developer.apple.com/library/ios/documentation/cocoa/Conceptual/DatesAndTimes/Articles/dtHist.html) if you're curious. – Sandy Chapman Apr 03 '14 at 14:51
3

One glaring glitch is:

[components setMonth:[year intValue]];    //setting month with year!
wmorrison365
  • 5,995
  • 2
  • 27
  • 40
2

You are calling setMonth twice, the second time with the value for year. Should be:

[components setDay:[day intValue]];
[components setMonth:[month intValue]];
[components setYear:[year intValue]];
Peter Rebholz
  • 503
  • 3
  • 7
1

Apart from the typo nowadays (2019) there is a more convenient syntax to access dictionary values with key subscription and properties with dot notation

NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *components = [[NSDateComponents alloc] init];
NSNumber *day = dataSource[@"day"];
NSNumber *month = dataSource[@"month"];
NSNumber *year = dataSource[@"year"];
components.day = day.integerValue;
components.month = month.integerValue;
components.year = year.integerValue;
NSDate *_date = [calendar dateFromComponents:components];

and there is another API without date components

NSCalendar *calendar = [NSCalendar currentCalendar];
NSNumber *day = dataSource[@"day"];
NSNumber *month = dataSource[@"month"];
NSNumber *year = dataSource[@"year"];
NSDate *_date = [calendar dateWithEra:1 year:year.integerValue month:month.integerValue day:day.integerValue hour:0 minute:0 second:0 nanosecond:0];
vadian
  • 274,689
  • 30
  • 353
  • 361