NSDateFormatter仍然parsing,而不是格式不正确
有一些问题parsingdate。 我有一个支持的格式数组,一旦我从API接收date(string),我尝试parsing它遍历格式,直到我得到一个有效的NSDate对象。
Xcode游乐场的片段 –
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"
为什么它parsingdate,即使格式显然不正确的给定的string? 无法find关于date格式化程序忽略分隔符的文档中的任何内容。
我知道正确的解决scheme是从API返回一个固定的格式,但想知道这里发生了什么?
谢谢。
看来NSDateFormatter
在parsingdatestring时非常宽松。 不幸的是,我找不到这个参考,但即使是
dateFormatIncorrect = "'aaa'dd'bbb'MM'ccc'yyyy'ddd'"
datestring“02/06/1987”被成功parsing。 有一个lenient
财产,但这是默认false
,明确设置没有任何区别。
作为一种解决方法 ,您可以将parsing的date转换回string,并且只有当结果等于原始string时,date才被接受:
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)
对不正确的date格式返回nil
。
通常,如果您使用固定的date格式,则还应将语言环境设置为“en_US_POSIX”
dateFormatter.locale = NSLocale(localeIdentifier: "en_US_POSIX")
(请参阅处理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 } }
这可能与NSDateFormatter在使用固定格式时无论如何将尊重用户设置有关
尽pipe原则上格式string指定了固定格式,但默认情况下,NSDateFormatter仍将用户的首选项(包括语言环境设置)考虑在内
所以可能是你的偏好定义的语言环境使用“/”作为分隔符,并满足“不正确的格式”。 即使情况并非如此,苹果在几个地方指出,NSDateFormatter可能并不一致。 所以请尝试设置一个固定的语言环境,看看是否有帮助
NSLocale *locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"]; [dateFormatter setLocale:locale];
请看这些链接的细节: 苹果技术笔记 。 注意与分隔符直接相关,但可能是相关的。
有一个类似的问题:
NSDateFormatter从无效input中返回date对象
在苹果提交了一个错误报告。 结果:不会被修改,因为更改会破坏工作代码,另外它更容错,从而提供某种方便。
请知道,我们的工程团队已经根据所提供的信息确定了此问题的行为。
看来,ICU的udat_parseCalendar()是非常宽松的,即使string不完全匹配格式,仍然可以parsing。 我们理解,在这些情况下,格式化程序返回nil,但是(1)没有简单的方法让我们知道inputstring与ICU允许的格式不匹配,并且不会抛出错误;(2)突然返回在这些情况下,几乎可以肯定是一个bincompat问题。
在我的情况下,我可以select修改unit testing,并在input无效的情况下更宽容,或者进行额外的检查(基于推荐的方法,这是接受的答案)是否由此产生的NSDate的string适合inputstring。