Swift 4中字符串转Date返回nil问题咨询(含复现代码)
解决DateFormatter.date(from:)返回nil的问题
嘿,我来帮你捋清楚这个问题!明明用同一个Formatter把Date转成了符合格式的字符串,再转回去却得到nil,这确实挺让人困惑的对吧?
可能的原因
这里的核心问题大概率和时区或者Locale设置有关:
- 夏令时导致的时间缺失:当你解析
"2018 03 30"这个字符串时,DateFormatter会默认把它当成你设置的TimeZone.current时区里的当天00:00:00。如果你的当前时区在2018年3月30日那天有夏令时切换(比如部分欧洲时区会把时钟往前调1小时,直接跳过0点),那这个时间点根本不存在,date(from:)自然就返回nil了。 - Locale的潜在干扰:你设置了
Locale(identifier: "en"),但这个Locale还是可能受系统区域设置影响。解析固定格式的日期字符串时,更稳妥的是用专门用于机器解析的en_US_POSIX,它不会随系统设置变动。
解决方案
给你两种靠谱的修复思路:
方式一:优化Formatter配置,规避时区坑
把Locale换成en_US_POSIX,同时可以调整时区或者确保解析的时间点存在:
let formatter = DateFormatter() formatter.locale = Locale(identifier: "en_US_POSIX") // 改用官方推荐的解析专用Locale formatter.dateFormat = "yyyy MM dd" formatter.timeZone = TimeZone.current let stringDate = formatter.string(from: Date()) // 得到"2018 03 30" // 解析时如果担心0点不存在,可以临时把时区改成UTC(UTC没有夏令时问题) formatter.timeZone = TimeZone(secondsFromGMT: 0) if let currentDate = formatter.date(from: stringDate) { print(currentDate) } else { print("解析失败") }
方式二:跳过无意义的来回转换
其实你完全没必要把Date转成字符串再转回去!如果你的目标只是获取当前日期的Date对象,直接用Date()就够了,这是最简洁也最不容易出错的方式:
let currentDate = Date() // 直接获取当前日期时间 // 如果需要展示成"YYYY MM DD"格式,再用Formatter转成字符串即可 let formatter = DateFormatter() formatter.locale = Locale(identifier: "en_US_POSIX") formatter.dateFormat = "yyyy MM dd" formatter.timeZone = TimeZone.current let stringDate = formatter.string(from: currentDate)
额外提示
- 解析固定格式的日期字符串时,一定要用
en_US_POSIXLocale,这是Apple官方明确推荐的做法,能避开很多系统区域设置带来的奇怪问题。 - 尽量避免无意义的Date与String来回转换,既浪费性能,还容易踩到时区、夏令时这类隐形的坑。
内容的提问来源于stack exchange,提问作者Waleed Saad Jebreen
相关产品推荐
相关产品推荐

