在 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 字符串的确切值是多少? dtnil...因为日期未转换。 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日期转换为本地时间以获取本地通知

iOS:将 UTC NSDate 转换为本地时区

在 Swift 中将日期从 GMT+1 转换为 UTC 时的困惑

在python中将日期时间从PDT转换为UTC

如何在Javascript中将日期转换为其他时区[重复]

将 UTC 日期时间全局转换为用户指定的本地日期时间