简体   繁体   中英

iOS - NSDateFormatter dateFromString returns nil only in one case

I'm testing some values for a date format ( "dd-MM-yyyy" ) and there's a special case that I can't explain:

var datef = NSDateFormatter()
datef.dateFormat = "dd-MM-yyyy";
var date_a = "02-01-1990"
var date_b = "01-01-1990"
var date_f_a = datef.dateFromString(date_a);
var date_f_b = datef.dateFromString(date_b);

data_f_a returns Jan 2, 1990, 12:00 AM, but date_f_b returns nil. Any other date will return the expected value, except for January 1st, 1990.

If I add datef.lenient = true date_f_b is no longer nil, but I shouldn't need to do that. Why is it an invalid date?

EDIT 1: It happens the same if I use DateFormatter() :

使用Swift版本3

EDIT 2: Xcode version: 8.1

After a few comments, it has been determined that the code in the question is being run with the locale of es_PE . This is the country of Peru. The date in question is January 1, 1990. By default, NSDateFormatter uses the local timezone and when parsing date strings that have no time, midnight is assumed.

In Peru, in the year 1990, day light savings began at midnight, January 1st, 1990. This means that clocks went from December 31, 1989 at 11:59:59pm straight to January 1, 1990 at 1:00:00am. There was no midnight on January 1, 1990.

This is why the attempt to convert the string 01-01-1990 failed for this user. There was no midnight for this date in Peru (and possibly a few other locales, if any, that had day light saving start at the same time). Most people testing this code would claim it works just fine since most people testing this code don't live in Peru.

I found a useful website with helpful information. See http://www.timeanddate.com/time/change/peru/lima?year=1990 for details about Peru and day light savings time. Note that in 1989 and 1991, Peru did not use day light savings time.

For xCode 7.3 You need to use NSDateComponents

var datef = NSDateFormatter()
datef.dateFormat = "dd-MM-yyyy";

var dtCompo = NSDateComponents()
dtCompo.day = 2
dtCompo.month = 1
dtCompo.year = 1990
let cal = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)!
var date_f_a = cal.dateFromComponents(dtCompo)

dtCompo = NSDateComponents()
dtCompo.day = 1
dtCompo.month = 1
dtCompo.year = 1990
var date_f_b = cal.dateFromComponents(dtCompo)

var date_f_a_string = datef.stringFromDate(date_f_a!)
var date_f_b_string = datef.stringFromDate(date_f_b!)

print(date_f_a_string)
print(date_f_b_string)

Output will 在此处输入图片说明 xCode 8.1

var datef = DateFormatter()
datef.dateFormat = "dd-MM-yyyy";

var dtCompo = DateComponents()
dtCompo.day = 2
dtCompo.month = 1
dtCompo.year = 1990
let cal = NSCalendar(calendarIdentifier: NSCalendar.Identifier.gregorian)!
var date_f_a = cal.date(from: dtCompo)

dtCompo = DateComponents()
dtCompo.day = 1
dtCompo.month = 1
dtCompo.year = 1990
var date_f_b = cal.date(from: dtCompo)

var date_f_a_string = datef.string(from: date_f_a!)
var date_f_b_string = datef.string(from: date_f_b!)

print(date_f_a_string)
print(date_f_b_string)

Output will 在此处输入图片说明

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM