You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift中带可选纪元的年份日期格式化问题

解决不同日历下年份格式化的纪元位置问题

要实现和iOS原生日历一致的年份显示(自动根据日历调整纪元的有无和位置),可以通过以下两种方式处理:

方法一:利用本地化日期样式提取年份部分

系统的DateFormatter本地化样式会自动根据日历和Locale适配纪元显示规则,我们可以先获取完整的本地化日期字符串,再提取年份相关部分:

let date = Date()
let formatter = DateFormatter()
formatter.calendar = targetCalendar // 替换为你需要的日历(如日本历、佛历、公历)
formatter.locale = Locale(identifier: "en_US")

// 获取长格式本地化日期
let fullDateString = formatter.localizedString(from: date, dateStyle: .long, timeStyle: .none)

// 提取年份和纪元部分(处理不同日历的格式)
var yearDisplayString = fullDateString
// 日本历格式类似 "Reiwa 5年1月1日",去掉日期部分
if targetCalendar.identifier == .japanese {
    yearDisplayString = fullDateString.components(separatedBy: "年")[0]
}
// 佛历格式类似 "January 1, 2566 BE",提取年份和BE
else if targetCalendar.identifier == .buddhist {
    let components = fullDateString.components(separatedBy: ", ")
    yearDisplayString = components[1]
}
// 公历格式类似 "January 1, 2023",提取年份
else if targetCalendar.identifier == .gregorian {
    let components = fullDateString.components(separatedBy: ", ")
    yearDisplayString = components[1]
}

print(yearDisplayString)
// 日本历输出 Reiwa 5
// 佛历输出 2566 BE
// 公历输出 2023

方法二:动态调整日期格式模板

如果不想处理字符串,可以根据日历类型动态设置格式模板的顺序,让系统自动适配:

let date = Date()
let formatter = DateFormatter()
formatter.calendar = targetCalendar
formatter.locale = Locale(identifier: "en_US")

// 根据日历设置模板顺序
switch targetCalendar.identifier {
case .japanese:
    // 日本历需要纪元在前,年份在后
    formatter.setLocalizedDateFormatFromTemplate("GGGG y")
    // 强制调整格式顺序(因为en_US locale下默认是y G,需要手动修改)
    if let currentFormat = formatter.dateFormat, currentFormat == "y G" {
        formatter.dateFormat = "G y"
    }
case .buddhist:
    // 佛历使用默认的y G即可
    formatter.setLocalizedDateFormatFromTemplate("y G")
case .gregorian:
    // 公历只显示年份
    formatter.setLocalizedDateFormatFromTemplate("y")
default:
    formatter.setLocalizedDateFormatFromTemplate("y")
}

print(formatter.string(from: date))
// 日本历输出 Reiwa 5
// 佛历输出 2566 BE
// 公历输出 2023

说明

目前iOS的DateFormatter没有完全无需判断日历的内置方法来自动适配所有日历的纪元位置,因为纪元的显示顺序由Locale的日期格式规则决定(比如en_US locale对日本历的默认顺序是年份在前,而原生日历应用采用了纪元在前的显示逻辑)。上述两种方法都能实现需求,其中方法一无需修改格式模板,通过字符串提取适配;方法二则通过少量的日历判断来调整格式,更贴近系统格式化逻辑。

内容的提问来源于stack exchange,提问作者mikro098

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 10:32:34