Swift DateFormatter格式化日期时月份全部变为1如何解决?
问题原因
问题来自两个核心错误:
- 格式符使用错误:
dateFormat里的大写 DD 代表一年中的第几天,你输入的22对应每年第22天,自然落在1月,所以月份始终显示为1月。月中的日期需要使用小写 dd。 - 格式转换逻辑错误:
dateFormatter.string(from:)方法接收的参数是Date类型,你直接传入字符串会报错,缺少「输入字符串转Date」的步骤,且你需要两个格式配置:一个匹配输入字符串的解析格式,一个匹配你期望输出的展示格式。
修复后代码
let testDate: String = "2020-11-22-11:00" print("start date: ", testDate, " reformatted date: ", reformatDate(dateString: testDate) ?? "转换失败") func reformatDate(dateString: String) -> String? { // 定义输入格式解析器,把输入字符串转成Date类型 let inputFormatter = DateFormatter() inputFormatter.dateFormat = "yyyy-MM-dd-HH:mm" // 此处把大写DD替换为小写dd inputFormatter.timeZone = TimeZone(abbreviation: "UTC") inputFormatter.locale = Locale(identifier: "en_US_POSIX") // 固定locale避免系统语言影响格式解析 guard let date = inputFormatter.date(from: dateString) else { return nil // 格式不匹配解析失败时返回空 } // 定义输出格式器,把Date转成目标展示格式 let outputFormatter = DateFormatter() outputFormatter.dateFormat = "dd-MM-yyyy hh:mm a" outputFormatter.timeZone = TimeZone(abbreviation: "UTC") outputFormatter.locale = Locale(identifier: "en_US_POSIX") // 避免AM/PM随系统语言变化 return outputFormatter.string(from: date) }
运行后输出为:start date: 2020-11-22-11:00 reformatted date: 22-11-2020 11:00 AM,符合预期。
额外注意项
- 所有涉及固定格式的日期转换都要设置
locale为en_US_POSIX,避免用户系统区域、语言设置影响格式解析,导致线上偶发转换失败。 - 不要复用同一个DateFormatter同时做解析和输出,容易因为修改格式后忘记重置导致逻辑错误。
内容的提问来源于stack exchange,提问作者firebaser
相关产品推荐
相关产品推荐

