iOS 13+ 下Swift日期格式化:字符串转DD-MM-YYYY格式Date对象
解决日期字符串解析与格式化问题
首先明确:Date对象本身没有格式,它本质是时间戳。你要完成的是两步操作:
- 将输入的带时区的日期字符串解析为Date实例
- 将Date实例格式化为
dd-MM-yyyy格式的字符串(注意:DD代表一年中的第几天,你需要的“一个月中的几号”应该用dd;YYYY是周年概念,日常日期用yyyy(公历年)更准确)
你的两种实现中的问题
第一种实现的错误
Date().formatted(...)是将当前日期转为带格式的字符串,不是解析用的格式规则,完全不匹配输入字符串的解析需求try! Date(strategy: expectedFormat)用法错误,init(strategy:)需要的是ParseStrategy类型,不是普通字符串,强行用try!会直接崩溃- 函数参数
key未被使用,也没有传入要解析的目标字符串
第二种实现的错误
DateFormatter.dateFormat(fromTemplate:options:locale:)返回的是字符串格式模板,不是DateFormatter实例,不能直接加()调用- 模板里的
DD、YYYY格式符使用错误,应该替换为dd、yyyy - 参数
options需要传具体数值(通常传0),locale不能传Locale?,要传具体的Locale实例(解析ISO格式时用en_US_POSIX更可靠) - 未设置时区,输入字符串带
+0000(UTC时区),解析时不对应设置会导致结果偏差
正确实现
如果是从JSON中解析日期字符串并格式化为目标格式,可以这么写:
func formattedAirdate(for key: String) -> String? { // 1. 从JSON中取出日期字符串 guard let dateString = self[key] as? String else { return nil } // 2. 配置解析用的DateFormatter,匹配输入字符串格式:"yyyy-MM-dd HH:mm:ss ZZZZ" let inputFormatter = DateFormatter() inputFormatter.locale = Locale(identifier: "en_US_POSIX") inputFormatter.timeZone = TimeZone(identifier: "UTC") inputFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss ZZZZ" // 3. 解析为Date实例 guard let date = inputFormatter.date(from: dateString) else { return nil } // 4. 配置格式化用的DateFormatter,输出dd-MM-yyyy格式 let outputFormatter = DateFormatter() outputFormatter.locale = Locale.current // 也可以指定你需要的locale outputFormatter.dateFormat = "dd-MM-yyyy" // 5. 转成目标格式的字符串 return outputFormatter.string(from: date) }
如果你的需求只是把输入字符串解析为Date实例(不需要转成字符串),可以简化为:
func parseAirdate(for key: String) -> Date? { guard let dateString = self[key] as? String else { return nil } let formatter = DateFormatter() formatter.locale = Locale(identifier: "en_US_POSIX") formatter.timeZone = TimeZone(identifier: "UTC") formatter.dateFormat = "yyyy-MM-dd HH:mm:ss ZZZZ" return formatter.date(from: dateString) }
补充说明
解析ISO格式的日期字符串,也可以用Foundation的ISO8601DateFormatter,代码更简洁:
func parseAirdateWithISOFormatter(for key: String) -> Date? { guard let dateString = self[key] as? String else { return nil } let isoFormatter = ISO8601DateFormatter() isoFormatter.formatOptions = [.withFullDate, .withTime, .withTimeZone] return isoFormatter.date(from: dateString) }
内容的提问来源于stack exchange,提问作者Sam
相关产品推荐
相关产品推荐

