Swift日期字符串格式转换问题:将2 January 2020转为2nd Jan, 2020
解决Swift日期格式转换问题:"2 January 2020" → "2nd Jan, 2020"
你的代码没生效的核心原因是输入日期格式不匹配,另外还要处理日期序数词(比如2nd、1st这类)的显示——DateFormatter并没有直接支持序数词的格式符,得额外处理。下面一步步给你修复:
问题分析
你调用formatDateFromDateTimeString(dateString: "2 January 2020")时,用的是默认的inputFormat("yyyy-MM-dd'T'HH:mm:ss"),但输入字符串是"2 January 2020",格式完全不匹配,导致inputDateFormatter.date(from: dateString)返回nil,最终只能返回空字符串。
另外,要输出2nd这种带序数词的日期,DateFormatter的dateFormat无法直接实现,需要单独处理日期数字的后缀逻辑。
修复后的代码
static func formatDateFromDateTimeString(dateString: String, inputFormat: String = "yyyy-MM-dd'T'HH:mm:ss", outputFormat: String = "dd MMM yyyy | hh:mm a") -> String { let inputDateFormatter = DateFormatter() // 设置对应输入字符串的格式,匹配"2 January 2020" inputDateFormatter.dateFormat = inputFormat // 固定区域为en_US_POSIX,避免系统区域设置干扰解析 inputDateFormatter.locale = Locale(identifier: "en_US_POSIX") guard let date = inputDateFormatter.date(from: dateString) else { return "" } // 处理日期序数词后缀逻辑 let calendar = Calendar.current let day = calendar.component(.day, from: date) let daySuffix: String = { switch day { case 1, 21, 31: return "st" case 2, 22: return "nd" case 3, 23: return "rd" default: return "th" } }() let outputDateFormatter = DateFormatter() // 先生成不带序数词的基础格式字符串 outputDateFormatter.dateFormat = "d MMM, yyyy" outputDateFormatter.locale = Locale(identifier: "en_US_POSIX") var formattedDate = outputDateFormatter.string(from: date) // 将日期数字替换为带后缀的版本 formattedDate = formattedDate.replacingOccurrences(of: "\(day)", with: "\(day)\(daySuffix)") return formattedDate }
正确调用方式
因为你的输入格式是"d MMMM yyyy",所以调用时必须指定inputFormat参数:
let result = formatDateFromDateTimeString(dateString: "2 January 2020", inputFormat: "d MMMM yyyy") print(result) // 输出:2nd Jan, 2020
关键改动说明
- 匹配输入格式:调用时传入
inputFormat: "d MMMM yyyy",让DateFormatter能正确解析"2 January 2020"格式的字符串。 - 序数词处理:通过Calendar获取日期的日分量,根据数字返回对应的后缀(st/nd/rd/th),再替换到格式化后的字符串中。
- 固定Locale:指定
en_US_POSIX避免系统区域设置影响日期的解析和格式化,保证在不同地区都能正确处理英文日期。
内容的提问来源于stack exchange,提问作者A J
相关产品推荐
相关产品推荐

