如何用ISO8601DateFormatter实现自定义日期与时间格式转换?
问题原因
你二次格式化返回nil的核心问题是逻辑颠倒:你用ISO8601DateFormatter把原始ISO字符串转成Date对象之后,应该直接用这个原始Date做目标格式的输出,而不是把第一次转出来的纯日期字符串再拿去转Date,纯日期字符串里根本没有时间信息,当然匹配不到时间格式的规则。
1. 输出MM-dd-yyyy格式(月-日-年)
不用硬拆字符串,拿到ISO转出来的原始Date后,用普通DateFormatter自定义格式即可:
func formatDateToMMDDYYYY(tempDay: String) -> String? { // 第一步:把ISO8601字符串转成Date对象 let isoFormatter = ISO8601DateFormatter() guard let date = isoFormatter.date(from: tempDay) else { return nil // 避免非法输入强制解包崩溃 } // 第二步:用普通DateFormatter输出目标格式 let targetFormatter = DateFormatter() targetFormatter.timeZone = .current // 按当前时区转换 targetFormatter.dateFormat = "MM-dd-yyyy" return targetFormatter.string(from: date) }
调用示例:输入"2021-11-26T15:48:43Z",输出为"11-26-2021"。
2. 输出12小时制时间格式(如11:13pm)
同样基于原始Date对象转换,自定义dateFormat即可,直接设置符号就能输出小写的am/pm:
func formatDateTo12HourTime(tempDay: String) -> String? { let isoFormatter = ISO8601DateFormatter() guard let date = isoFormatter.date(from: tempDay) else { return nil } let targetFormatter = DateFormatter() targetFormatter.timeZone = .current targetFormatter.dateFormat = "hh:mma" targetFormatter.amSymbol = "am" targetFormatter.pmSymbol = "pm" return targetFormatter.string(from: date) }
调用示例:输入"2021-11-26T15:48:43Z",如果当前时区是东八区的话,输出为"11:48pm"。
优化建议
如果需要同时输出两种格式,没必要重复创建ISO8601DateFormatter做重复转换,可以先把原始ISO字符串转成Date对象缓存,再分别用不同的目标formatter输出即可。
内容的提问来源于stack exchange,提问作者Arturo
相关产品推荐
相关产品推荐

