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

Ios NSDateFormatter仍在解析,但格式不正确,ios,swift,nsdateformatter,Ios,Swift,Nsdateformatter,解析日期时遇到一些问题。我有一个受支持的格式数组,一旦我从API接收到日期(字符串),我就会尝试通过格式迭代解析它,直到得到一个有效的NSDate对象 Xcode游乐场的一个片段-- 为什么即使给定字符串的格式显然不正确,它仍要解析日期?在文档中找不到有关日期格式化程序忽略分隔符的任何内容 我意识到正确的解决方案是从API返回一个固定格式,但我想知道这里发生了什么 谢谢。在解析日期字符串时,NSDateFormatter似乎非常宽松。 不幸的是,我找不到这方面的参考资料,但即使 dateForm

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

Xcode游乐场的一个片段--

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

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


谢谢。

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

dateFormatIncorrect = "'aaa'dd'bbb'MM'ccc'yyyy'ddd'"
已成功解析日期字符串“02/06/1987”。有一个
lencient
属性, 但默认情况下,这是
false
,显式设置它没有任何区别

作为一种解决方法,您可以将解析的日期转换回字符串,并且只有在 结果等于原始字符串,接受日期:

extension NSDateFormatter {

    func checkedDateFromString(string : String) -> NSDate? {
        if let date = self.dateFromString(string) {
            if self.stringFromDate(date) == string {
                return date
            }
        }
        return nil
    }
}
使用此自定义扩展

dateFormatter.checkedDateFromString(dateString)
对于不正确的日期格式,返回
nil


通常,如果使用固定日期格式,还应设置区域设置 到“en_US_POSIX”

(见附件)。然而,这并没有什么区别 特别的问题


Swift 3的更新:

extension DateFormatter {

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

这可能与NSDateFormatter在使用固定格式时无论如何都会尊重用户设置这一事实有关

虽然原则上格式字符串指定固定格式,但是 默认NSDateFormatter仍然接受用户的首选项(包括 语言环境设置)将被考虑在内

因此,您的首选项中定义的区域设置可能使用“/”作为分隔符,并且满足“不正确的格式”。即使情况并非如此,苹果在几个地方指出,NSDateFormatter可能不会始终如一地采取行动。因此,尝试如下设置一个固定的区域设置,看看这是否有帮助

NSLocale *locale = [[NSLocale alloc] 
    initWithLocaleIdentifier:@"en_US_POSIX"];
[dateFormatter setLocale:locale];
有关详细信息,请参阅以下链接:。注:与分离器直接相关,但也可能与之相关。

有类似问题:

在苹果公司提交了一份缺陷报告。 结果:不会固定,因为更改可能会破坏工作代码,此外,它更具容错性,因此提供了某种便利

请知道,我们的工程团队已确定该问题 根据所提供的信息,按预期行为

看来ICU的udat_parseCalendar()非常宽大,而且仍然有效 即使字符串与格式不完全匹配,也能够进行分析。 我们理解在这些情况下更倾向于格式化程序返回nil 但是(1)没有简单的方法让我们知道输入字符串 与格式不匹配,因为ICU允许并且不会抛出 错误和(2)在这些情况下突然返回nil几乎是错误的 当然,这是一个不相容的问题


在我的例子中,我可以选择修改单元测试,在输入无效的情况下更加宽容,或者进行额外检查(基于推荐的方法,这是本文接受的答案),检查结果NSDate的字符串是否适合输入字符串。

@TheParamagneticCroissant它没有翻转日期/月份。这两个格式化程序以不同的顺序指定它们。dMy和Mdy.MM表示月份,dd表示月份的日期。因此dd.MM.yyyy是正确的format@Fogmeister哦,是的,没错。月和日的位置是故意不同的。我很好奇为什么它会被解析为第一种格式(可能不正确,不是正确的单词),即使分隔符不匹配(/和)。这很有趣。即使使用
DateFormatError=“'aaa'dd'bbb'MM'ccc'yyyy'ddd'”
日期格式化程序也会转换它。您尝试过吗?这也是我的第一个想法,但将区域设置设置为“en_US_POSIX”并不能解决我的测试用例中的问题。这是我尝试过的第一件事情之一,但不幸的是没有成功。谢谢,虽然不太理想,但在API更新以解决此问题之前,这将起到作用。@sharoni:欢迎您。我试图找到任何解释这种行为的文档,但没有成功。你可能会考虑向苹果提交一份bug报告。1实际测试:DI可能会使用正则表达式来验证格式。
extension DateFormatter {

    func checkedDate(from: String) -> Date? {
        if let date = date(from: from), string(from: date) == from {
            return date
        }
        return nil
    }
}
NSLocale *locale = [[NSLocale alloc] 
    initWithLocaleIdentifier:@"en_US_POSIX"];
[dateFormatter setLocale:locale];