You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 17:16:17