Swift中能否结合doesRelativeDateFormatting使用自定义日期格式?
解决Swift中同时支持相对日期和自定义非相对日期格式的问题
我来帮你搞定这个需求!要实现既显示today/tomorrow这类友好的相对日期,又在非相对场景下使用Wed, Feb 10 '18这种自定义格式,我们可以通过组合DateFormatter的特性,再加上简单的判断逻辑来实现,具体方案如下:
核心思路
当开启doesRelativeDateFormatting后,DateFormatter会优先返回相对日期字符串(比如"Today"、"Tomorrow",具体取决于本地化设置)。我们可以先尝试用带相对格式化的formatter处理日期,如果返回的是相对字符串就直接用;如果不是,再切换到自定义格式的formatter来生成目标样式。
完整代码实现
你可以把这个逻辑封装成一个Date的扩展,方便在项目里随时调用:
extension Date { func formattedWithRelativeOrCustomStyle() -> String { // 1. 配置支持相对格式化的formatter let relativeFormatter = DateFormatter() relativeFormatter.doesRelativeDateFormatting = true // 设置基础dateStyle触发相对格式化判断 relativeFormatter.dateStyle = .short relativeFormatter.locale = Locale(identifier: "en_US_POSIX") // 根据需求调整本地化 // 2. 先尝试获取相对日期字符串 let relativeString = relativeFormatter.string(from: self) // 3. 判断是否为相对日期:对比关闭相对格式化的结果 let nonRelativeFormatter = DateFormatter() nonRelativeFormatter.dateStyle = .short nonRelativeFormatter.locale = relativeFormatter.locale let nonRelativeString = nonRelativeFormatter.string(from: self) if relativeString != nonRelativeString { // 返回相对日期字符串 return relativeString } else { // 使用自定义格式生成非相对日期 let customFormatter = DateFormatter() customFormatter.dateFormat = "EEE, MMM d ''yy" customFormatter.locale = relativeFormatter.locale return customFormatter.string(from: self) } } }
关键细节说明
- 相对日期判断逻辑:通过对比开启/关闭相对格式化的formatter输出结果,就能知道当前日期是否触发了相对格式化——两者结果不同,说明是相对日期场景。
- 自定义格式字符串解析:
"EEE, MMM d ''yy"完全匹配你想要的样式:EEE:星期缩写(如Wed)MMM:月份缩写(如Feb)d:不带前导零的日期数字''yy:带单引号的两位年份(如'18)
- 本地化适配:如果是中文环境,把
locale改成Locale(identifier: "zh_CN"),相对日期会自动变成"今天"/"明天",完全符合用户的语言习惯。
用法示例
// 今天的日期 let today = Date() print(today.formattedWithRelativeOrCustomStyle()) // 输出 "Today" // 明天的日期 let tomorrow = Calendar.current.date(byAdding: .day, value: 1, to: today)! print(tomorrow.formattedWithRelativeOrCustomStyle()) // 输出 "Tomorrow" // 一个非近期的日期 let pastDate = Calendar.current.date(byAdding: .day, value: -30, to: today)! print(pastDate.formattedWithRelativeOrCustomStyle()) // 输出类似 "Wed, Feb 10 '18" 的结果
内容的提问来源于stack exchange,提问作者francisaugusto
相关产品推荐
相关产品推荐

