Why NSDateFormatter is returning null for a 19/10/2014 in a Brazilian time zone?
We can reproduce your problem by explicitly setting the time zone to “Brazil/East”:
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[])
{
@autoreleasepool {
NSString *dateString = @"19/10/2014";
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
dateFormatter.timeZone = [NSTimeZone timeZoneWithName:@"Brazil/East"];
[dateFormatter setDateFormat:@"dd/MM/yyyy"];
NSDate *myDate = [dateFormatter dateFromString:dateString];
NSLog(@"myDate = %@", myDate);
}
return 0;
}
Here's the output:
2014-06-06 14:22:28.254 commandLine[31169:303] myDate = (null)
Since you didn't give a time in your dateString
, the system assumes midnight. But midnight on that date doesn't exist in the Brazilian time zone.
Brazil changes from BRT (daylight-saving time zone) to BRST (non-daylight-saving time zone) on October 19, 2014, skipping directly from the last moment of “18/10/2014” to “19/10/2014 01:00:00”.
Since “19/10/2014 00:00:00” doesn't exist, NSDateFormatter
returns nil
. I think this is bad behavior on the part of NSDateFormatter
, but we have to deal with it. -[NSDateFormatter dateFromString:]
eventually calls CFDateFormatterGetAbsoluteTimeFromString
, which uses the udat_parseCalendar
function from the International Components for Unicode (icu) library to parse the date.
You can work around the problem by making the parser use noon instead of midnight as the default time. No time zones change to/from daylight saving time at noon. Let's write a helper function that returns noon of some arbitrary date in a given time zone:
static NSDate *someDateWithNoonWithTimeZone(NSTimeZone *timeZone) {
NSDateComponents *components = [[NSDateComponents alloc] init];
components.timeZone = timeZone;
components.era = 1;
components.year = 2001;
components.month = 1;
components.day = 1;
components.hour = 12;
components.minute = 0;
components.second = 0;
return [[NSCalendar autoupdatingCurrentCalendar] dateFromComponents:components];
}
Then we set the date formatter's defaultDate
to this noon date:
int main(int argc, const char * argv[])
{
@autoreleasepool {
NSString *dateString = @"19/10/2014";
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
dateFormatter.timeZone = [NSTimeZone timeZoneWithName:@"Brazil/East"];
dateFormatter.dateFormat = @"dd/MM/yyyy";
dateFormatter.defaultDate = someDateWithNoonWithTimeZone(dateFormatter.timeZone);
NSDate *myDate = [dateFormatter dateFromString:dateString];
NSLog(@"myDate = %@", myDate);
}
return 0;
}
And here's the output:
2014-06-06 14:52:31.939 commandLine[31982:303] myDate = 2014-10-19 14:00:00 +0000
NSDateFormatter dateFromString return null
Your code is correct. _x0010_
If the device is set to AM/PM time and requested string format is set to @"yyyy-MM-dd HH:mm:ss" dateFromString will return nil. Try setting the locale like :
[dateFormatter setLocale:[[NSLocale alloc] initWithLocaleIdentifier:@"en_US"]];
Why my NSDateFormatter returns null?
Use HH instead of hh.
hh usually is 12 hour time while HH is usually 24 hour time.
[dateFormatter setDateFormat:@"dd-MM-yyyy HH:mm:ss"];
A good official reference for this, as linked by Apple themselves, is here. Another good table is here, as mentioned by Zaph.
Date formatter in Objective-C returns null
Set your date formatter's locale to EN_US_POSIX
. That way, the device's region will not alter the formatter.
NSLocale *locale = [[NSLocale alloc]
initWithLocaleIdentifier:@"EN_US_POSIX"];
[dateFormatter setLocale:locale];
NSDateFormatter returns NULL
- (NSString *)formatDate:(NSDate *)date
{
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"EEEE, MMMM dd"];
NSString *returnString = [dateFormatter stringFromDate:date];
NSLog(@"Formatted Date: %@", returnString);
return returnString;
}
You need to use stringFromDate:
, not dateFromString:
.
I get this logged
2014-01-12 00:14:20.096 StackOverFlowDate[84614:a0b] Formatted Date: Sunday, January 12
Why NSDateFormatter returns NULL on 24h locals with a 12h time setup?
Solved! (inspired by the answers above)..
To solve the issue i am creating a specific Locale, then phrasing the stringToDate using this locale. Then i am creating another Locale with the default users preferences and phrasing the dateBackToString using that locale..
+(NSString *) formatTime: (NSString *)timeToBeFormatted
{
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
//ADDED//
NSLocale *enUSPOSIXLocale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"];
[dateFormat setLocale:enUSPOSIXLocale];
[dateFormat setDateFormat:@"HH"];
NSDate *date = [[NSDate alloc] init];
date = [dateFormat dateFromString:timeToBeFormatted];
//ADDED//
NSLocale *defualtLocale = [[NSLocale alloc] init];
[dateFormat setLocale:defualtLocale];
[dateFormat setTimeStyle:NSDateFormatterShortStyle];
timeToBeFormatted = [dateFormat stringFromDate:date];
return timeToBeFormatted;
}
I guess its quite costly for older devices but in the era of ARC and strong phones it works ;)
iOS Date Formatter Returns Null
Please use below code
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss.SSSZZZZ"];
NSString *dueDateString = [NSString stringWithFormat:@"2014-07-11T15:21:42.207+02:00"];
NSDate *dateFromApi = [dateFormatter dateFromString:dueDateString];
[dateFormatter setDateFormat:@"yyyy/MM/dd"];
NSString *finalDateString = [dateFormatter stringFromDate:dateFromApi];
NSLog(@"dueDateString %@", dueDateString);
NSLog(@"dateFromApi %@", dateFromApi);
NSLog(@"finalDateString%@", finalDateString);
Related Topics
MySQL and Swift - Upload Image and File || Would It Be Better to Use Alamofire
iOS Rich Notification Didreceivenotificationrequest Is Not Fired
"Rctbundleurlprovider.H" File Not Found - Appdelegate.M
Sending Push Notifications to iOS from Pwa
Presentviewcontroller and Displaying Navigation Bar
What's Dead & Exploded in Swift's Exception Stack
To Create a New Uiwindow Over the Main Window
Icloud + Coredata - How to Avoid Pre-Filled Data Duplication
Uitableview:Viewforheaderinsection: Not Called During Reloaddata:
Swift 3.0, Alamofire 4.0 Extra Argument 'Method' in Call
Gmsgeocoder Reversegeocodecoordinate: Completionhandler: on Background Thread
Set Uitableview Content Inset Permanently
Refresh Certain Row of Uitableview Based on Int in Swift
Allow Unverified Ssl Certificates in Wkwebview
How to Detect If Code Is Running in Main App or App Extension Target