Swift中DateFormatter校验日期格式时非法输入被误判为有效日期
问题背景
需求是校验输入日期字符串是否完全匹配指定的dd/MM/yyyy日期格式,初始实现代码如下,但测试发现传入本应校验失败的非法日期值时,代码会错误判定日期有效:
- 非法值示例:仅三位年份的
"12/10/199"、分隔符错误的"12/10.199"
初始实现代码:
import Foundation let inputValue = "12/10/199" // 传入"12/10.199"时也会被判定为有效 let dateFormatter = DateFormatter() dateFormatter.dateFormat = "dd/MM/yyyy" if let dateOfBirth = dateFormatter.date(from: inputValue) { print("Valid date \(dateOfBirth)") // 非法值会错误命中该分支 } else { print("Invalid date") }
控制台错误输出:
Valid date 0199-10-11 18:06:32 +0000
异常产生原因
DateFormatter默认开启了宽松解析模式(isLenient属性默认值为true),该模式下解析器不会要求输入字符串和指定的dateFormat完全逐位匹配:
- 数字段长度不足时会自动补位:比如要求4位年份的
yyyy格式传入3位值199时,会自动在高位补0解析为公元0199年 - 非数字的分隔符不匹配时会自动容错跳过,不会直接判定格式无效,因此分隔符写错的
12/10.199也能被解析通过
严格匹配修复方案
将DateFormatter的isLenient属性设置为false,即可关闭宽松解析,要求输入字符串必须和指定格式完全匹配才能解析成功,修正后的代码如下:
import Foundation let inputValue = "12/10/199" // 传入"12/10.199"等非法格式也会正确判定无效 let dateFormatter = DateFormatter() dateFormatter.dateFormat = "dd/MM/yyyy" dateFormatter.isLenient = false // 启用严格格式校验 // 可选:固定公历历法,避免设备当前历法设置(如佛历、伊斯兰历)导致解析偏差 dateFormatter.calendar = Calendar(identifier: .gregorian) if let dateOfBirth = dateFormatter.date(from: inputValue) { print("Valid date \(dateOfBirth)") } else { print("Invalid date") }
调整后再传入三位年份、错误分隔符的非法值时,解析会正确返回nil,命中无效日期分支。
内容的提问来源于stack exchange,提问作者user121095
相关产品推荐
相关产品推荐

