在 iOS 中将 UTC 日期时间转换为本地日期时间
Posted
技术标签:
【中文标题】在 iOS 中将 UTC 日期时间转换为本地日期时间【英文标题】:Converting UTC date time to local date time in iOS 【发布时间】:2018-06-06 04:39:55 【问题描述】:我正在尝试将 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(from: date) 无法识别日期。因此,将一个 nil 值分配给 dt。
对于所有系统语言一般使用日期时间格式的任何建议都将是可观的。
【问题讨论】:
您传递给此函数的date
字符串的确切值是多少?
dt
是 nil
...因为日期未转换。 dt!
强制解包选项会导致运行时错误。
@rmaddy 感谢您的友好回复,我传递给函数的日期字符串是 "6/5/18 12:47:54 PM"
@MahendraGP 是的,您对日期未转换的事情是正确的。如果系统语言设置为 English(India),则此完全相同的代码可以正常工作,但如果我将系统语言更改为 Japanese,则会引发错误
【参考方案1】:
当您尝试解析固定格式的日期字符串时,您需要将格式化程序的语言环境设置为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"
【讨论】:
上面的修复就像魅力一样,我使用了你建议的日期和时间样式以避免歧义。再次感谢您的修复和建议。以上是关于在 iOS 中将 UTC 日期时间转换为本地日期时间的主要内容,如果未能解决你的问题,请参考以下文章
iOS将NSDate的UTC日期转换为本地时间以获取本地通知