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
相关产品推荐
相关产品推荐

