我正在尝试将UTC日期时间转换为本地日期时间,以下是我的代码。
func dateTimeStatus(date: String) -> String{
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "MM/dd/yy hh:mm:ss a"
dateFormatter.timeZone = TimeZone(abbreviation: "UTC")
let dt = dateFormatter.date(from: date)
dateFormatter.timeZone = TimeZone.current
dateFormatter.dateFormat = "MM/dd/yy hh:mm:ss a"
return dateFormatter.string(from: dt!) // .string(from: dt!)
}
当系统(iPhone或iPad)语言设置为英语(印度)时,上述代码集有效。如果我将语言更改为日语,则会抛出异常,如下所示。
线程1:致命错误:在解包可选值时意外发现nil
在return
声明。
我非常清楚我正在弄乱dateFormatter,因为dateFormatter.date(来自:date)无法识别日期。因此,为dt分配了一个零值。
对于通常使用所有系统语言的日期时间格式的任何建议都是值得注意的。
答案 0 :(得分:0)
每当您尝试解析固定格式的日期字符串时,都需要将格式化程序的语言环境设置为en_US_POSIX
的特殊语言环境。这涉及许多可能的问题,包括用户的区域和语言,以及用户的12/24小时设置。
dateFormatter.locale = Locale(identifier: "en_US_POSIX")
然后将其重置为用户的区域设置以及时区。
dateFormatter.locale = Locale.current
如果您收到意外的日期字符串,也应该避免强制解包。
更新的代码:
func dateTimeStatus(date: String) -> String {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "MM/dd/yy hh:mm:ss a"
dateFormatter.locale = Locale(identifier: "en_US_POSIX")
dateFormatter.timeZone = TimeZone(secondsFromGMT: 0)
if let dt = dateFormatter.date(from: date) {
dateFormatter.locale = Locale.current
dateFormatter.timeZone = TimeZone.current
dateFormatter.dateFormat = "MM/dd/yy hh:mm:ss a"
return dateFormatter.string(from: dt)
} else {
return "Unknown date"
}
}
在向用户展示日期/时间时,您还应考虑使用日期和时间样式而不是固定格式。这可确保日期为友好格式。在你的情况下,你有一个真正的问题。
假设你得到“06/05/18 10:30:00 am”的结果。
那是几号?取决于您居住的地点,可能是2018年6月5日。可能是2018年5月6日。可能是2006年5月18日。这是非常模糊的。
最好使用类似的东西:
func dateTimeStatus(date: String) -> String {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "MM/dd/yy hh:mm:ss a"
dateFormatter.locale = Locale(identifier: "en_US_POSIX")
dateFormatter.timeZone = TimeZone(secondsFromGMT: 0)
if let dt = dateFormatter.date(from: date) {
let userFormatter = DateFormatter()
userFormatter.dateStyle = .medium // Set as desired
userFormatter.timeStyle = .medium // Set as desired
return userFormatter.string(from: dt)
} else {
return "Unknown date"
}
}