NSDateFormatter dateFromString Always Returns nil - ios

I want to apologize ahead of time for asking a repeat question, but none of the other solutions have worked for me yet. Every time I try to pass a date string to the dateFromString function I get nil. I haven't read anywhere that things have changed since the iOS 7 update, but I am current on updates if that makes a difference on whether or not this still works the same way.
This is the code I'm using to create the date from string:
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setTimeZone:[NSTimeZone systemTimeZone]];
[dateFormat setLocale:[NSLocale systemLocale]];
[dateFormat setDateFormat:#"yyyy-MM-dd hh:mm:ss"];
[dateFormat setFormatterBehavior:NSDateFormatterBehaviorDefault];
NSDate *date = [[NSDate alloc] init];
date = [dateFormat dateFromString:dateString];
return date;
I've set up my dateFormat based on all the solutions I've read to solve this problem, but none of these settings have solved by problem. The systemLocale is definitely set up for English so that should not be causing any issues.
This is the dateString I'm passing to dateFromString:
Wednesday, October 9, 2013 at 2:40:29 PM Pacific Daylight Time
Thanks for the help!

There are two issues here:
The format of date string the formatter is expecting (#"yyyy-MM-dd hh:mm:ss") is different from the format of the date string you're trying to parse (#"EEEE, MMMM d, yyyy 'at' h:mm:ss a zzzz").
Setting the formatter's locale to [NSLocale systemLocale] is causing [dateFormat dateFromString:] to return nil. Set it to [NSLocate currentLocale].
The full code for the formatter should be:
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setTimeZone:[NSTimeZone systemTimeZone]];
[dateFormat setLocale:[NSLocale currentLocale]];
[dateFormat setDateFormat:#"EEEE, MMMM d, yyyy 'at' h:mm:ss a zzzz"];
[dateFormat setFormatterBehavior:NSDateFormatterBehaviorDefault];
NSDate *date = [dateFormat dateFromString:dateString];

Yet another way to get nil is if you use hh and your hours are on the 24 hr clock and > 12, in that case, you need HH (or H, for zero-padded).
That is:
Format: yyyy-MM-DD hh:mm:ss, string: "2016-03-01 13:42:17" will return nil
Format: yyyy-MM-DD HH:mm:ss, string: "2016-03-01 13:42:17" will return the date you expect.
Hat-tip to #neilco (see comments below his answer) for this. If you like this answer, please up-vote his, too.

According to NSDateFormatter documentation :
When working with fixed format dates, such as RFC 3339, you set the
dateFormat
property to specify a format string.
If your date format is 2017-06-16T17:18:59.082083Z then dateFormat property should look like this yyyy-MM-dd'T'HH:mm:ss.SSSSSSZ.
Swift 3
let dateFormatter = DateFormatter()
let date = "2017-06-16T17:18:59.082083Z"
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSSSSZ"
let result = dateFormatter.date(from: date) // 2017-06-16 17:18:59 +0000

Your date format doesn't match the string that you're passing, your dateString should be in this formate as per your [dateFormat setDateFormat:#"yyyy-MM-dd hh:mm:ss"];
2013-10-09 02:40:29
nil means dateFormat object was unable to parse your string.

In case anybody is stuck on the same hilarious edge case as me:
"2020-03-08T02:00:00" will return nil as long as you're in a locale that follows Daylight Savings Time, because that hour is skipped and simply doesn't exist.

You're trying to use dateFromString but the Format you have passed to your Formatter is different of what you're using in dateString.
Try to use this config in your dateFormat: E',' M d',' yyyy 'at' hh:mm:ss aa z

Don't forget to escape "yyyy/MM/dd' 'HH:mm:ss" space symbols

Related

iOS Date conversion from string bug [duplicate]

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

Date giving wrong year on Device [duplicate]

What is exact difference between 'YYYY' and 'yyyy'. I read in this link, it states that
A common mistake is to use YYYY. yyyy specifies the calendar year
whereas YYYY specifies the year (of “Week of Year”), used in the ISO
year-week calendar. In most cases, yyyy and YYYY yield the same
number, however they may be different. Typically you should use the
calendar year.
But when I try to use
NSString *stringDate = #"Feb 28, 2013 05:30pm";
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"MMM dd, yyyy hh:mma"];
NSDate *date=[dateFormatter dateFromString:stringDate];
NSLog(#"Date 1 : %#",date); //2013-02-28 12:00:00 +0000
NSString *stringDatee = #"Feb 28, 2013 05:30pm";
NSDateFormatter *dateFormatterr = [[NSDateFormatter alloc] init];
[dateFormatterr setDateFormat:#"MMM dd, YYYY hh:mma"];
NSDate *datee=[dateFormatterr dateFromString:stringDatee];
NSLog(#"Date 2 : %#",datee); //2013-01-05 12:00:00 +0000
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"MMM dd, YYYY hh:mma"];
NSString *dateString = [dateFormat stringFromDate:datee];
NSLog(#"date 3 : %#", dateString); //Jan 05, 2013 05:30PM
As here, result to date and datee different, which I understood, but why result of date 2 and date 3 are different? As I am creating date from string and reversing same to string again, but output mismatches?
Has anybody knows reason about same?. Though it specifies week of year, still I should get result same.
Thanks..
EDIT :-
If I code
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"MMM dd, YYYY hh:mma"];
NSString *dateString = [dateFormatterr stringFromDate:[NSDate date]];
NSLog(#"date: %#", dateString); //Feb 28, 2013 04:37PM
If results me proper result, but same which I pass as string to date I get 2013-01-05 12:00:00 +0000, check date 2 of NSLog, Strange result, why?
Also when using a date format string using the correct format is important.
#"YYYY" is week-based calendar year.
#"yyyy" is ordinary calendar year.
You can go through the whole blog, its a good to give it a look
https://web.archive.org/web/20150423093107/http://realmacsoftware.com/blog/working-with-date-and-time
http://realmacsoftware.com/blog/working-with-date-and-time (dead link)
A common mistake is to use
YYYY. yyyy specifies the calendar year whereas YYYY specifies the year
(of “Week of Year”), used in the ISO year-week calendar. In most
cases, yyyy and YYYY yield the same number, however they may be
different. Typically you should use the calendar year.
from Apple Docs
dd/MMM/YYYY - e.g.:1 01/Jan/2000; answer : 19/dec/1999
(see weekly calendar December month last Monday
suppose leaf year + 1 day)
dd/MMM/yyyy - eg: ordinary - no problem.
All answers differentiating yyyy and YYYY are right answers for another question. The question itself refers to another thing.
Why does these two values are different? (extracted from question)
NSLog(#"Date 2 : %#",datee); //2013-01-05 12:00:00 +0000
NSLog(#"Date 3 : %#", dateString); //Jan 05, 2013 05:30PM
The answer here #P.J is that they are not really different in value. When you log an NSDate (which is Date 2) you are getting the full description of your object which happens to be on UTC Timezone. This logic does not happen when logging Date 3 because it was already converted to a String and applied your Timezone.
For printing Date 3 the 'same way' as you are getting Date 2. You should specify UTC TimeZone for Date 3. Something like this :
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"MMM dd, YYYY hh:mma"];
[dateFormat setTimeZone:[NSTimeZone timeZoneWithAbbreviation:#"UTC"]];
NSString *dateString = [dateFormat stringFromDate:datee];
NSLog(#"date 3 : %#", dateString);
Hope this helps.
tl;dr the Timezone

Converting Date string with date format as "2015-11-09 06:54:00 UTC" to NSDate

The string I get from server is in the format like "2015-11-09 06:54:00 UTC" I want to convert
NSDateFormatter* dateFormatter = [[NSDateFormatter alloc] init];
dateFormatter.dateFormat = #"yyyy-MM-dd'T'HH:mm:ssZ";
NSDate* date = [dateFormatter dateFromString:dateString];
[dateFormatter setDateFormat:#"dd MMM yyyy hh:mm a"];
NSString* formattedDate = [dateFormatter stringFromDate:date];
I tried with date formatter to be dateFormatter.dateFormat = #"yyyy-MM-dd'T'HH:mm:ssZ";
Still I get the formatted date as nil.
I don't understand how to convert this string to a proper NSDate. Please suggest.
Try the below code snippet;
NSString *dateString = #"2015-11-09 06:54:00 UTC";
NSDateFormatter* dateFormatter = [[NSDateFormatter alloc] init];
dateFormatter.dateFormat = #"yyyy-MM-dd HH:mm:ss Z";
NSDate* date = [dateFormatter dateFromString:dateString];
dateFormatter setDateFormat:#"dd MMM yyyy hh:mm a"];
NSString* formattedDate = [dateFormatter stringFromDate:date];
NSLog(#"Formatted Date: %#",formattedDate);
I could say "try the code below", but that is useless.
Look at your formatting string. It says what the date formatter expects in the string.
Look at your date string.
Compare them. They don't match. The 'T' in the formatting string isn't some kind of black magic. It means "I expect a letter T in the date string". There is no letter T in the date string, that's why it doesn't work.
Read Apple's documentation carefully, and take note of the bit where it refers to the Unicode standard. And read that document at www.unicode.org carefully - There is a HUGE difference between yyyy and YYYY, and between MM and MMM, and between HH and hh, and if you don't read this and learn this, you cannot write code that gives the desired result.

NSDateFormatter DateFromString return nil

I Know it may be got answered a lot here but i think i have a different case
I'm getting the string date in the following format
2014-04-14 16:04:07 +0000
And using the following code
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"yyyy-MM-dd HH:mm:ss"];
NSDate *startDate = [dateFormat dateFromString:st];
But startDate always give me nil
You should handle zone too. Correct variant:
[dateFormat setDateFormat:#"yyyy-MM-dd HH:mm:ss Z"];
Also consider to use nice lib for date formatting ISO8601DateFormatter. It will handle your format automatically.
[dateFormat setDateFormat:#"yyyy-MM-dd HH:mm:ss"];
If that format does not match the format of the date string exactly, the result of dateFromString: is nil.
It doesn't so it is.

iOS NSDate Comparison works differently when the 24-Hour Time in date settings toggles between ON and OFF?

Team,
I am comparing the date which is formed from string using NSDateFormatter with the iOS system date. The below statement returns true when the system date time settings is set with 24-Hour Time ON, but the same code returns false when 24-Hour Time OFF.
Problematic Code:
if ([(NSDate*)[NSDate date] compare:currDate] == NSOrderedAscending) {
// -- Code -- This is executed only when the 4-Hour Time ON
}
I am confused. The string using which I am getting the date is in 24 hours format. Is this a problem? Or anything else?
Date Formatting Code:
-(NSDate *)getDateFromString:(NSString *)dateString{
NSDateFormatter* fmt = [[NSDateFormatter alloc] init];
[fmt setDateFormat:#"dd MMM yyyy hh:mm:ss"];
[fmt setTimeZone:[NSTimeZone systemTimeZone]];
[fmt setFormatterBehavior:NSDateFormatterBehaviorDefault];
return [fmt dateFromString:dateString];
}
See Apple's Technical Q&A 1480.
You need to set the date formatter's locale to the special locale of en_US_POSIX. You also need to specify a 24-hour hour format - HH, not hh.
-(NSDate *)getDateFromString:(NSString *)dateString{
NSLocale *posix = [[NSLocale alloc] initWithLocaleIdentifier:#"en_US_POSIX"];
NSDateFormatter* fmt = [[NSDateFormatter alloc] init];
[fmt setLocale:posix];
[fmt setDateFormat:#"dd MMM yyyy HH:mm:ss"];
return [fmt dateFromString:dateString];
}
23 May 2013 15:37:00 is a 24 hour format string.So the correct date is obtained using the 24 hour format date formatter .Thats it
So use
[fmt setDateFormat:#"dd MMM yyyy HH:mm:ss"];

Resources