The behavior depends on which timeZone
the formatter using.
For example: America/Sao_Paulo
In Sao Paulo, http://www.timeanddate.com/time/change/brazil/sao-paulo?year=2015
Sunday, 18 October 2015, 00:00:00 clocks are turned forward 1 hour to
Sunday, 18 October 2015, 01:00:00 local daylight time instead
That means, there is no 2015-10-18 00:00:00
in Sao Paulo.
And as for NSDateFormatter
, when it receives no time information from string, it assumes the time is 00:00:00
in its timezone. That's why it returns nil
.
let formatter = NSDateFormatter()
formatter.locale = NSLocale(localeIdentifier: "en_US_POSIX")
formatter.timeZone = NSTimeZone(name: "America/Sao_Paulo")
formatter.dateFormat = "yyyy-MM-dd HH:mm"
formatter.dateFromString("2015-10-18 00:00") // -> nil
formatter.dateFromString("2015-10-18 00:30") // -> nil
formatter.dateFromString("2015-10-18 01:00") // -> non nil
As @LeoDabus stated, when you specify .calendar
on the formatter:
it assumes the time is 00:00:00
in its timezone.
it will assume the start of the day for that date.
let formatter = NSDateFormatter()
formatter.locale = NSLocale(localeIdentifier: "en_US_POSIX")
formatter.timeZone = NSTimeZone(name: "America/Sao_Paulo")
formatter.dateFormat = "yyyy-MM-dd"
formatter.calendar = NSCalendar(identifier: NSCalendarIdentifierGregorian)
formatter.dateFromString("2015-10-17") // -> Oct 17, 2015, 12:00 AM
formatter.dateFromString("2015-10-18") // -> Oct 18, 2015, 1:00 AM
formatter.dateFromString("2015-10-19") // -> Oct 19, 2015, 12:00 AM