在 iOS 中将 UTC 日期时间转换为本地日期时间

Ram*_*thy 2 time date ios swift dateformatter

我正在尝试将 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!)
}
Run Code Online (Sandbox Code Playgroud)

当系统(iPhone或iPad)语言设置为英语(印度)时,上面的代码集有效。如果我将语言更改为日语,则会抛出异常,如下所示。

线程 1:致命错误:在解包可选值时意外发现 nil

return声明中。

我很清楚我弄乱了 dateFormatter 因为dateFormatter.date(from: date) 无法识别日期。因此,将 nil 值分配给 dt。

对于所有系统语言通用使用日期时间格式的任何建议都是值得赞赏的。

rma*_*ddy 6

每当您尝试解析固定格式日期字符串时,都需要将格式化程序的区域设置设置为特殊区域设置en_US_POSIX. 这处理了许多可能的问题,包括用户的区域和语言,以及用户的 12/24 小时设置。

dateFormatter.locale = Locale(identifier: "en_US_POSIX")
Run Code Online (Sandbox Code Playgroud)

然后将其重置为用户的区域设置以及时区。

dateFormatter.locale = Locale.current
Run Code Online (Sandbox Code Playgroud)

您还应该避免强制展开,以防收到意外的日期字符串。

更新的代码:

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"
    }
}
Run Code Online (Sandbox Code Playgroud)

在向用户呈现日期/时间时,您还应该考虑使用日期和时间样式而不是固定格式。这可确保日期采用友好的格式。就你而言,你有一个真正的问题。

假设您得到的结果是“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"
    }
}
Run Code Online (Sandbox Code Playgroud)