iOS中如何实现日期格式化器本地化,修复中文月份不显示问题
问题
我在项目中使用以下Swift函数格式化时间:
func formatTime() -> String { let dateFormatter = DateFormatter() let tempLocale = dateFormatter.locale dateFormatter.locale = Locale(identifier: "en_US") dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'" dateFormatter.timeZone = TimeZone.init(abbreviation: "UTC") dateFormatter.amSymbol = "AM" dateFormatter.pmSymbol = "PM" if let callTime = callTime { if let date = dateFormatter.date(from: callTime) { dateFormatter.timeZone = TimeZone.current dateFormatter.dateFormat = "MMMM dd yyyy hh:mm a" dateFormatter.locale = tempLocale let dateString = dateFormatter.string(from: date) return dateString } else { return "" } } else { return "" } }
当前函数输出为:
January 18 2023 04:36 PM
我的项目支持英文和中文两种语言,但切换至中文后,日期字符串仍保持英文格式,我希望将月份本地化显示为中文,请问该如何实现?
解决方案
问题根源有两点:
- 输出格式化阶段将
locale设回了初始化DateFormatter时的tempLocale,这个值不会跟随系统语言切换,导致始终用初始locale输出。 - 硬编码了
amSymbol和pmSymbol,强制显示AM/PM,无法适配中文的“上午/下午”标识。
修改后的代码如下:
func formatTime() -> String { let dateFormatter = DateFormatter() // 解析UTC格式日期时,用en_US_POSIX确保解析稳定(Apple官方推荐) dateFormatter.locale = Locale(identifier: "en_US_POSIX") dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ" dateFormatter.timeZone = TimeZone(abbreviation: "UTC") guard let callTime = callTime, let date = dateFormatter.date(from: callTime) else { return "" } // 输出时使用系统当前locale,自动适配语言 dateFormatter.timeZone = TimeZone.current dateFormatter.dateFormat = "MMMM dd yyyy hh:mm a" dateFormatter.locale = Locale.current return dateFormatter.string(from: date) }
额外优化说明:
- 用
guard简化空值判断逻辑,代码更简洁。 - 解析ISO格式日期时改用
en_US_POSIX,避免因系统区域设置差异导致解析失败。 - 移除硬编码的上午/下午符号,让
DateFormatter根据当前语言自动生成对应标识。
修改后切换到中文环境,输出会变为类似一月 18 2023 04:36 下午的本地化格式。
内容的提问来源于stack exchange,提问作者SpH
相关产品推荐
相关产品推荐

