Sharon Watinsan
Sharon Watinsan

Reputation: 9850

Setting NSDate from NSString not working

myObject.theEnd and myObject.theStart are strings and it has the date format of Thu Feb 31 like wise...

NSDateFormatter *format=[[NSDateFormatter alloc] init];
        [format setDateFormat:@"EEE MMM dd"]; 
        NSDate *end = [format dateFromString:myObject.theEnd];
        NSDate *start = [format dateFromString:myObject.theStart];
        NSDate *current = [NSDate date];

When theEnd is Thu Feb 31, NSDate *end shows as 1970-5-19 14:30 +0000. It is the same with NSDate *start and NSDate *current.

Why is this ? and How can i solve this ?

Upvotes: 0

Views: 155

Answers (1)

mattjgalloway
mattjgalloway

Reputation: 34912

I bet theEnd is not showing as 1970-05-19 14:30 +0000. I bet it's showing as (null) since there is never a 31st February! e.g. I get:

NSDateFormatter *format = [[NSDateFormatter alloc] init];
[format setDateFormat:@"EEE MMM dd"]; 
NSDate *end = [format dateFromString:@"Thu Feb 31"];
NSLog(@"end = %@", end);

=>

2012-05-20 16:38:31.620 test-date[42307:707] end = (null)

Also I bet that you are in a timezone that is 9.5 hours east of UTC. And 1970-05-19 14:30 +0000 is actually what you will then get when you parse today's date of Sun May 20. For instance I am currently in BST so UTC+0100 and I get:

NSDateFormatter *format = [[NSDateFormatter alloc] init];
[format setDateFormat:@"EEE MMM dd"]; 
NSDate *start = [format dateFromString:@"Sun May 20"];
NSLog(@"start = %@", start);

=>

2012-05-20 16:38:31.621 test-date[42307:707] start = 1970-05-19 23:00:00 +0000

Since it's parsing to 1970-05-20 00:00:00 (there's no year so that component is "0" = 1970) in the current timezone, which is 1970-05-19 23:00:00 +0000 in UTC.

If you want to get around that problem, then set the timezone of the formatter to UTC:

[format setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];

To get the year into the current year you could do something like this:

NSDateFormatter *format = [[NSDateFormatter alloc] init];
[format setDateFormat:@"EEE MMM dd"];
[format setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];

NSDate *start = [format dateFromString:@"Sun May 20"];
NSLog(@"start = %@", start);

NSDate *today = [NSDate date];

NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *todayComponents = [gregorian components:NSYearCalendarUnit fromDate:today];
NSDateComponents *startComponents = [gregorian components:(NSMonthCalendarUnit | NSDayCalendarUnit) fromDate:start];

[startComponents setYear:[todayComponents year]];
[startComponents setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];

start = [gregorian dateFromComponents:startComponents];

NSLog(@"start = %@", start);

It's not that pretty, but it works. Alternatively you could just append the current year to the string you pass into the formatter and add yyyy to the formatter style:

NSDateFormatter *format = [[NSDateFormatter alloc] init];
[format setDateFormat:@"EEE MMM dd yyyy"];
[format setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];

NSDate *today = [NSDate date];
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *todayComponents = [gregorian components:NSYearCalendarUnit fromDate:today];

NSString *dateString = [NSString stringWithFormat:@"Sun May 20 %i", [todayComponents year]];

NSDate *start = [format dateFromString:dateString];
NSLog(@"start = %@", start);

Upvotes: 6

Related Questions