I am reading the tutorial provided by Raywenderlich, Chapter 29 What’s New with Testing, and run into a strange problem.
Following is the code in the tutorial converting a string into date:
// Convert date string to date.
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss zzz"
var date: NSDate? = dateFormatter.dateFromString(dateString)
The dateString is of the form
2014-06-21 14:56:00 EST
However, the date variable is always nil.
NOTE: when playing this code in the playground, it works properly, as the image shows:
I am working in iOS SDK 8.0. Is it a bug of the SDK?
Updated
I am testing using a latest iPod Touch with iOS 8.
When you set a dateFormat
string you must also set the locale
property to something that is compatible with the format provided. Otherwise the locale will be based on the device settings which may not be compatible.
The date format you provided here will work with the "en" locale but it will not work with many others, such as "eu". Here's an example:
let dateString = "2014-06-21 14:56:00 EST"
let localeStr = "eu" // this will give nil
let localeStr = "us" // this will succeed
let dateFormatter = NSDateFormatter()
dateFormatter.locale = NSLocale(localeIdentifier: localeStr)
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss zzz"
var date: NSDate? = dateFormatter.dateFromString(dateString)
The problem here is "EST" which only exists in the north america. In all other locales it is an invalid timezone. If you change your date string to this:
"2014-06-21 14:56:00 UTC-5"
Then it the date will correctly format no matter what value locale
is set to.
NSDateFormatter
's behaviors are heavily depends on it's locale
.
By default, it uses device locale.
If you want consistent result from it, You should manually specify the locale
. In most cases, en_US_POSIX
is the best.
The document says:
If you're working with fixed-format dates, you should first set the locale of the date formatter to something appropriate for your fixed format. In most cases the best locale to choose is en_US_POSIX, a locale that's specifically designed to yield US English results regardless of both user and system preferences. en_US_POSIX is also invariant in time (if the US, at some point in the future, changes the way it formats dates, en_US will change to reflect the new behavior, but en_US_POSIX will not), and between platforms (en_US_POSIX works the same on iPhone OS as it does on OS X, and as it does on other platforms).
Like this:
let dateString = "2014-06-21 14:56:00 EST"
let dateFormatter = NSDateFormatter()
dateFormatter.locale = NSLocale(localeIdentifier: "en_US_POSIX")
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss zzz"
var date: NSDate? = dateFormatter.dateFromString(dateString)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With