Setting NSDate from NSString not working - iphone

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 ?

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

Related

List days in calendar year

I am wanting to list (NSLog) all the dates of the Georgian calendar year (2013). I have managed to get the current date using the following:
NSCalendar* calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents* components = [calendar components:NSDayCalendarUnit
fromDate:currDate];
NSInteger day = [components day];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateStyle:NSDateFormatterLongStyle];
NSString *dateString = [dateFormatter stringFromDate:currDate];
NSLog(#"%#", dateString);
How can I print out all the dates in 2013?
NSDateFormatter* dateFormatter = [NSDateFormatter new] ;
dateFormatter.dateStyle = NSDateFormatterLongStyle ;
NSDate* today = [NSDate date] ;
NSCalendar* calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar] ;
NSDateComponents* thisYearComponents = [calendar components:NSYearCalendarUnit fromDate:today] ;
NSDate* firstDateInThisYear = [calendar dateFromComponents:thisYearComponents] ;
NSDateComponents* addDaysComponents = [NSDateComponents new] ;
addDaysComponents.day = 0 ;
while ( TRUE ) {
NSDate* nextDateInThisYear = [calendar dateByAddingComponents:addDaysComponents toDate:firstDateInThisYear options:0] ;
NSDateComponents* yearOfNextDateComponents = [calendar components:NSYearCalendarUnit fromDate:nextDateInThisYear] ;
if ( yearOfNextDateComponents.year == thisYearComponents.year )
NSLog(#"%#", [dateFormatter stringFromDate:nextDateInThisYear]) ;
else
break ;
addDaysComponents.day += 1 ;
}
The WWDC 2011 session 117 - Performing Calendar Calculations is a great source of information. It covers why it's better practice to, in a loop, add n days to a fixed reference date, rather than repeatedly adding 1 day to the most recently used date.
It also suggests using noon (12pm) instead of midnight (12am) for NSDates in which you don't care about the time, because Daylight Saving Time causes midnight to not exist for certain dates in certain places. But I didn't bother to do that in my example.
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"yyyy-MM-dd"];
NSDate *date = [dateFormatter dateFromString:#"2013-01-01"];
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *components = [calendar components:kCFCalendarUnitYear fromDate:date];
while ([components year] < 2014) {
NSDateFormatter *dateFormatter1 = [[NSDateFormatter alloc] init];
[dateFormatter1 setDateStyle:NSDateFormatterLongStyle];
NSString *dateString = [dateFormatter1 stringFromDate:date];
NSLog(#"%#", dateString);
date = [NSDate dateWithTimeInterval:60*60*24 sinceDate:date];
components = [calendar components:kCFCalendarUnitYear fromDate:date];
}

Get time difference between two specific time zones in iPhone?

e.g. I want the time difference between asia/kolkata time and asia/dubai.
NSInteger differenceInSeconds = [timeZone1 secondsFromGMT] - [timeZone2 secondsFromGMT];
Note that this gives the current time difference between those timezones. If the two timezones observe daylight savings at different times of year, the time difference depends on when you evaluate this. If this matters to you, you should use secondsFromGMTForDate: to get the timezone offset at a specific date.
NSDate *now = [NSDate date];
NSDateFormatter *df = [[NSDateFormatter alloc] init] ;
[df setTimeStyle:NSDateFormatterFullStyle];
[df setTimeZone:[NSTimeZone timeZoneWithName:Str]];//str = timezone1(for you its kolkata)
[df setDateFormat:#"dd-MM-yyyy HH:mm"];
NSString *S1 = [df stringFromDate:now];
[df setDateFormat:#"dd-MM-yyyy HH:mm"];
NSDate *dd = [df dateFromString:S1];
//dd = date1 as per timezone
NSLog(#"dd > %#",dd);
[df release];
NSDate *dt = [NSDate date];
NSLog(#"dt = %#",dt);
NSDateFormatter *df1 = [[NSDateFormatter alloc] init];
[df1 setTimeStyle:NSDateFormatterFullStyle];
[df1 setTimeZone:[NSTimeZone timeZoneWithName:Str2]];//str2=timezone2(for you its dubai)
[df1 setDateFormat:#"dd-MM-yyyy HH:mm"];
NSString *S2 = [df1 stringFromDate:dt];
[df setDateFormat:#"dd-MM-yyyy HH:mm"];
NSDate *dd1 = [df dateFromString:S2];
//dd1 = date2 as per timezone
NSLog(#"dd1 > %#",dd1);
NSCalendar *sysCalendar = [NSCalendar currentCalendar];
unsigned int unitFlags = NSHourCalendarUnit | NSMinuteCalendarUnit | NSDayCalendarUnit | NSMonthCalendarUnit;
NSDateComponents *conversionInfo = [sysCalendar components:unitFlags fromDate:dd toDate:dd1 options:0];
NSLog(#"Conversion: %dmin %dhours %ddays %dmoths",[conversionInfo minute], [conversionInfo hour], [conversionInfo day], [conversionInfo month]);
i'm usin this code and its working properly.

Get start date from week number

I've been trying and searching for over two days now.
The only thing I'm trying is to convert a week number "Week 50" to the start date of the week.
I've tried to convert with dateFromString like this:
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"w"];
NSDate *date = [dateFormat dateFromString:dateStr];
NSLog(#"date(%#)", date);
NSDateFormatter *formatting = [[NSDateFormatter alloc] init];
[formatting setDateFormat:#"YYYY/MM/dd"];
NSString *stringDate = [formatting stringFromDate:date];
NSLog(#"date: %#", stringDate);
[dateFormat release];
But both objects return (null) so it isn't of many help.
Regards
Have you tried the following:
NSDateComponents *comps = [[NSDateComponents alloc] init];
[comps setYear:2012];
[comps setWeek:50];
NSCalendar *cal = [NSCalendar currentCalendar];
NSDate *week50 = [cal dateFromComponents:comps];
You can try trimming the string to just the week number like "50" and then add the desired year number and use following:
NSString *dateStr=#"50 2011";
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"w YYYY"];
NSDate *date = [dateFormat dateFromString:dateStr];
NSLog(#"date(%#)", date);

Date/time conversion to user's local time - issue

My application grabs a date / time from a remote server which is alway in GMT +1 (UTC/GMT +1 hour) timezone.
The format the server is providing is :
24 08 2011 08:45PM
I would like to convert this time stamp into the equivalent time/date of the users time zone (the user can be anywhere in the world).
thus as an example :
24 08 2011 08:45PM coming from the server should be presented
24 08 2011 09:45PM to an Italian user (rome) (GMT + 1)
This code works on some timezones but i have a bad feeling that there is something very wrong about it and that there is a much more elegant way to do it
NSString *dateString = #"24 08 2011 09:45PM";
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"dd MM yyyy hh:mma"];
NSDate *dateFromString = [[[NSDate alloc] init] autorelease];
dateFromString = [dateFormatter dateFromString:dateString];
NSDate* sourceDate = dateFromString;
NSTimeZone* sourceTimeZone = [NSTimeZone timeZoneWithAbbreviation:#"BST"];
NSTimeZone* destinationTimeZone = [NSTimeZone systemTimeZone];
NSInteger sourceGMTOffset = [sourceTimeZone secondsFromGMTForDate:sourceDate];
NSInteger destinationGMTOffset = [destinationTimeZone secondsFromGMTForDate:sourceDate];
NSTimeInterval interval = destinationGMTOffset - sourceGMTOffset;
NSDate* destinationDate = [[NSDate alloc] initWithTimeInterval:interval sinceDate:sourceDate] ;
NSString *thePubDate = [dateFormatter stringFromDate:destinationDate];//[appLogic getPubDate];
NSLog(#"Result : %#",thePubDate);
[dateFormatter release];
//[dateFromString release];
[destinationDate release];
I will appreciate your thoughts and suggestions on the matter
Just set the timeZone in the dateFormatter, This code is enough
NSString *dateString = #"24 08 2011 09:45PM";
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"dd MM yyyy hh:mma"];
NSTimeZone* sourceTimeZone = [NSTimeZone timeZoneWithAbbreviation:#"BST"];
[dateFormatter setTimeZone:sourceTimeZone];
NSDate *dateFromString = [dateFormatter dateFromString:dateString];
The dateFromString will now have the date 24 08 2011 08:45PM(GMT).. Then to convert this to string with local time just code the following,
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"dd MM yyyy hh:mma"];
NSString *stringFromDAte = [dateFormatter stringFromDate:dateString];

iphone NSDate - get todays date and force the time

hopefully a quick one for someone! I am struggling to see why the code below isn't working. I am trying to get today's date (eg: 2010-09-10) and manually adding the time. It always seems to return 00:00:00 for the time though. any ideas where I'm going wrong?
NSDateFormatter *dateFormatter = [[[NSDateFormatter alloc] init] autorelease];
dateFormatter.dateFormat = #"yyyy-MM-dd";
NSString *actualDate = [dateFormatter stringFromDate:[NSDate date]];
NSDate *sDate = [dateFormatter dateFromString:[NSString stringWithFormat:#"%# %#", actualDate, #"01:00:00"]];
NSDate *eDate = [dateFormatter dateFromString:[NSString stringWithFormat:#"%# %#", actualDate, #"23:59:59"]];
The NSDate objects are returning the format 2010-09-10 00:00:00 +01:00 all the time. Somewhere it's just not picking up the time.... any ideas? many thanks.
* UPDATE *
The code below works. I did as suggested and accessed the elements and updated them.
unsigned unitFlags = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit;
NSDate *date = [NSDate date];
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *comps = [calendar components:unitFlags fromDate:date];
NSDateFormatter *dateFormatter = [[[NSDateFormatter alloc] init] autorelease];
dateFormatter.dateFormat = #"yyyy-MM-dd hh:mm:ss";
//update for the start date
[comps setHour:0];
[comps setMinute:0];
[comps setSecond:0];
NSDate *sDate = [calendar dateFromComponents:comps];
//update for the end date
[comps setHour:23];
[comps setMinute:59];
[comps setSecond:59];
NSDate *eDate = [calendar dateFromComponents:comps];
You should use NSCalendar instead then. It allows you to parse the current date and modify its components. Like you can initialize it with today's date and then set the time and then get an NSDate from it.
(Old answer: Because your formatter is configured to only recognize the date part. Add the time part to it (even though its name is NSDateFormatter, it will happily parse dates and times) and you will see the time too.)
I found this question today while looking to do the same thing, create an NSDate with a specific time today. The solution presented wasn't quite what I needed so I came up with this:
NSDate * date;
NSString * string, *timestamp;
NSDateFormatter * formatter;
timestamp = #"17:30";
formatter = [[[NSDateFormatter alloc] init] autorelease];
[formatter setDateFormat: #"yyyy-MM-dd "];
[formatter setTimeZone: [NSTimeZone localTimeZone]];
string = [formatter stringFromDate: [NSDate date]];
string = [string stringByAppendingString: timestamp];
[formatter setDateFormat: #"yyyy-MM-dd HH:mm"];
date = [formatter dateFromString: string];