NSDateFormatter仍在解析,但格式不正确

sha*_*oni 5 nsdateformatter ios swift

解析日期时遇到一些问题。我有一系列受支持的格式,一旦从API接收到日期(字符串),我就会尝试解析这些格式的迭代,直到获得有效的NSDate对象。

Xcode Playground的一个片段-

let dateString = "02/06/1987" // --> want to parse into this Feb 6, not Jun 2
let dateFormatIncorrect = "dd.MM.yyyy"
let dateFormatCorrect = "MM/dd/yyyy"
let dateFormatter = NSDateFormatter()

dateFormatter.dateFormat = dateFormatIncorrect
let date = dateFormatter.dateFromString(dateString)! // "Jun 2, 1987, 12:00 AM"

dateFormatter.dateFormat = dateFormatCorrect
let date2 = dateFormatter.dateFromString(dateString)! // "Feb 6, 1987, 12:00 AM"
Run Code Online (Sandbox Code Playgroud)

为什么即使给定的字符串格式明显不正确,也为什么要解析日期?在文档中找不到有关日期格式化程序的任何内容,忽略了分隔符。

我意识到正确的解决方案是从API返回固定格式,但想知道这里发生了什么?

谢谢。

Mar*_*n R 5

解析日期字符串NSDateFormatter时似乎非常宽松。不幸的是,我找不到这方面的参考,但即使有

dateFormatIncorrect = "'aaa'dd'bbb'MM'ccc'yyyy'ddd'"
Run Code Online (Sandbox Code Playgroud)

日期字符串“02/06/1987”被成功解析。有一个lenient属性,但这是false默认设置,显式设置它没有任何区别。

作为一种解决方法,您可以将解析后的日期转换回字符串,并且仅当结果等于原始字符串时,才会接受该日期:

extension NSDateFormatter {

    func checkedDateFromString(string : String) -> NSDate? {
        if let date = self.dateFromString(string) {
            if self.stringFromDate(date) == string {
                return date
            }
        }
        return nil
    }
}
Run Code Online (Sandbox Code Playgroud)

使用这个自定义扩展,

dateFormatter.checkedDateFromString(dateString)
Run Code Online (Sandbox Code Playgroud)

返回nil错误的日期格式。


通常,如果您使用固定日期格式,您还应该将语言环境设置为“en_US_POSIX”

dateFormatter.locale = NSLocale(localeIdentifier: "en_US_POSIX")
Run Code Online (Sandbox Code Playgroud)

(请参阅处理 NSDateFormatter 语言环境“feechur”的最佳方法是什么?)。但是,这对于这个特定问题没有区别。


Swift 3 更新:

extension DateFormatter {

    func checkedDate(from: String) -> Date? {
        if let date = date(from: from), string(from: date) == from {
            return date
        }
        return nil
    }
}
Run Code Online (Sandbox Code Playgroud)