NSDateFormatter will not parse string with timezone that includes colon - objective-c

I'm trying to transform #"Fri, 26 Aug 2011 10:51:00 +02:00" into an NSDate:
[dateFormatter setDateFormat:#"EEE, dd MMM yyyy HH:mm:ss Z"];
NSDate *date = [dateFormatter dateFromString:dateString];
I get nil as a result; what am I doing wrong?

You can use the getObjectValue:forString:range:error: method to parse dates that have the colon in the timezone:
// test date formatting
NSString *dateString = #"2012-04-11T18:34:19+00:00";
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
formatter.dateFormat = #"yyyy-MM-dd'T'HH:mm:ssZ";
NSDate *date;
NSError *error;
[formatter getObjectValue:&date forString:dateString range:nil error:&error];

The colon in the timezone (+02:00) is the issue. According to the Unicode Standard #35, 1..3 capital Z pattern denotes a RFC 822 time zone. RFC 822 time zones represent the offset from GMT (or UTC) and have the following format:
zone = "UT" / "GMT" ; Universal Time
...
...
/ ( ("+" / "-") 4DIGIT ) ; Local differential
; hours+min. (HHMM)
As you can see, there is no colon between hours and minutes of the time zone. Therefore, the time zone should be +0200.
The most proper solution would be to generate a unicode compliant date string in the first place, but if you are stuck with this format, you may need to preprocess the date string before you pass it to NSDateFormatter.
For example, a quick fix would be using stringByReplacingOccurrencesOfString to get rid of the colon in the time zone:
// dateString --> Fri, 26 Aug 2011 10:51:00 +02:00
dateString = [dateString stringByReplacingOccurrencesOfString:#":"
withString:#""
options:0
range:NSMakeRange(25, [dateString length] - 25)];
// dateString --> Fri, 26 Aug 2011 10:51:00 +0200
[dateFormatter setDateFormat:#"EEE, dd MMM yyyy HH:mm:ss Z"];
NSDate *date = [dateFormatter dateFromString:dateString];
// date --> 2011-08-26 08:51:00 +0000

No string manipulation required. Change your format string to:
[dateFormatter setDateFormat:#"EEE, dd MMM yyyy HH:mm:ss Z:00"];
I tested it and it parses the date you give just fine. When I print the date using [NSDate description], I get 2011-08-26 08:51:00 +0000, which is equivalent to the date given in the string.

Yeah, this is a common problem. A number of servers produce the date with the colon in the timezone, and NSDateFormatter can't (to my knowledge) be convinced to accept it. The solution is to cut out the colon somehow, as suggested.

Related

Custom date string to NSDate

I am trying to convert Mon, 01 Aug 2016 04:15 PM IST to NSDate
I tried using the below code but always stuck with nil. Please help
NSString *fullTime = #"Mon, 01 Aug 2016 04:15 PM IST";
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init];
[dateFormatter setDateFormat:#"EEE, dd MMM yyyy hh:mm a ZZZ"];
NSDate *tempTime = [dateFormatter dateFromString:fullTime];
You main issue is the IST in the date, IST is not a standard and can stand for many time zones:
IST Indian Standard Time UTC+05:30
IST Irish Standard Time UTC+01
IST Israel Standard Time UTC+02
The date formatter will not be able to correctly format the date since it does not know which timezone is meant.
If you can you should have the date changed or remove the IST part from the date.
Also you will need to add a locale to the date formatter you it knows in which language is used in the date string.
For english beste use en_US_POSIX:
dateFormatter.locale = [NSLocale localeWithLocaleIdentifier:#"en_US_POSIX"];
I tried your code.First it gives nil.Then I changed LocaleIdentifier to en_IN because
IST stands for both Israel Standard Time, and India Standard Time also it indicates this
NSString *strDate = #"Mon, 01 Aug 2016 04:15 PM IST";
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"EEE, dd MMM yyyy HH:mm a zzz"];
dateFormat.locale = [[NSLocale alloc] initWithLocaleIdentifier:#"en_IN"];
NSDate *dateStr = [dateFormat dateFromString:strDate];
NSLog(#"The date is - %#",dateStr);
The Printed Result is
The date is - 2016-08-01 06:45:00 +0000
Convert between date formats in Objective-C

Error with formatting time in objective-c

I am trying to format the date of a blog post pulled from an RSS feed to be displayed in a table cell. I set the string "dateString" equal to the date received from the XML parser and log the results. Then, I convert the date to a new format, log it to the console, and I receive "null." Which in return gives me a time interval of 0, and displays "seconds ago" in my cell. I think there could be an error in my date format, but I checked many sources.
NSString *dateString = nil;
dateString = [datearray objectAtIndex:indexPath.row];
NSLog(#"Date Posted: %#", dateString);//Log date posted
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"EEE, dd MMM yyyy HH:mm:ss ZZZ"];
NSDate *date = [dateFormat dateFromString:dateString];
NSLog(#"New Date: %#", date);//Log date posted
NSTimeInterval timeInterval = [date timeIntervalSinceNow];
NSLog(#"Time interval %f", timeInterval);
NSString *newTime = [timeIntervalFormatter stringForTimeInterval:timeInterval];
NSLog(#"New Time %#", newTime);
cell.dateLabel.text = [NSString stringWithFormat:#"%#", newTime];
Console Log:
2014-06-13 15:43:41.555 Cazenovia High School[13489:60b] Date Posted: Thu, 22 Aug 2013 13:33:44 +0000
2014-06-13 15:43:41.556 Cazenovia High School[13489:60b] New Date: (null)
2014-06-13 15:43:41.557 Cazenovia High School[13489:60b] Time interval 0.000000
2014-06-13 15:43:41.558 Cazenovia High School[13489:60b] New Time seconds ago
Edits:
Added the following lines, but still no change...
NSLocale *locale = [[NSLocale alloc] initWithLocaleIdentifier:#"en_US_POSIX"];
[dateFormat setLocale:locale];
that was quite clear after running the project, because it seems there is an extra new-line character at tail of the dateString.
technically, which string you are working with is "Thu, 22 Aug 2013 13:33:44 +0000\0x0a", that is why the parser cannot work with it using that formatter.
I've modified the formatter to EEE, dd MMM yyyy HH:mm:ss ZZZ\n and it works properly now, that is how my console looks:

DateFormatter keep returning null

I have a date i take from twitter :
NSString *date=[twt objectForKey:#"created_at"];
NSLog(#"%#",date);
NSDateFormatter *df = [ [NSDateFormatter alloc] init] ;
[df setDateFormat:#"dd-MM-yyyy HH:mm:ss"];
NSDate *newdate = [df dateFromString:date];
NSLog(#"new: %#",newdate); //null
the date is : Thu Jun 12 20:56:53 +0000 2014 and i get null on the new date .
What am i missing ?
the date formatter for that format (Thu Jun 12 20:56:53 +0000 2014) would be this:
"EEE MMM d HH:mm:ss Z yyyy"
rather than this "dd-MM-yyyy HH:mm:ss".
The date formatting string you've shared sure does't look like it matches the date you're getting from Twitter. The docs for dateFromString state...
A date representation of string interpreted using the receiver’s
current settings. If dateFromString: can not parse the string, returns
nil.
Read up!
http://unicode.org/reports/tr35/tr35-6.html#Date_Format_Patterns

NSDateFormatter return incorrect date from string

I have a method,
+ (NSDate *) convertToDateFrom:(NSString *) dateString
{
if (dateString == nil || [dateString isEqual:#""]) return nil; //return nil if dateString is empty
NSDateFormatter *df = [[NSDateFormatter alloc] init];
[df setDateFormat:#"EEEE, dd MMMM yyyy HH:mm"];
NSDate *date = [df dateFromString:dateString];
return date;
}
When I pass,
#"Monday, 21 November 2011 17:01" //Passed string
It returns a wrong date,
2011-11-21 23:14:00 +0000 // Output
I am not sure whether I am using those flags correctly or NSDateFormatter isn't properly converting my string to date.
Am I doing something wrong?
Thanks
The +0000 at the end of the date indicates GMT. All dates are stored relative to GMT; when you convert a date to a string or vice versa using a date formatter, the offset to your time zone is included. You can use NSDateFormatter's -setTimeZone: method to set the time zone used.
In short, you're not doing anything wrong in your code. Use [df stringFromDate:date]; to see that the date is correct. (You can also use NSDate's -descriptionWithCalendarFormat:timeZone:locale:.)
try using
df stringFromDate:date
Following worked on mine,
NSLog(#"Date for locale %#: %#",
[[dateFormatter locale] localeIdentifier], [df stringFromDate:date]);
gave me output as :
Date for locale en_US: Wednesday, 26 June 2013 15:50
Try setting the time zone and locale.
[df setLocale:[NSLocale currentLocale]];
[df setTimeZone:[NSTimeZone systemTimeZone]];

Objective-C: Unicode Date Format

I am trying to work out how to have the UNICODE representation of
Sun, 03 May 2009 19:58:58 -0700 as eee, dd MMM yyyy HH:mm:s ZZZZ or something. I can't seem to get this working precisely.
Use an NSDateFormatter. It lets you set a particular format string, using the format specifiers from the Unicode spec, then get the formatted date from a given NSDate object using stringFromDate:. Also consider reading Apple's doc about formatting dates. Example:
// Given some NSDate *date
NSDateFormatter *formatter = [[[NSDateFormatter alloc] init] autorelease];
[formatter setDateFormat:#"eee, dd MMM yyyy HH:mm:ss ZZZZ"];
NSString *formattedDate = [formatter stringFromDate:date];