如何在 Swift 4 中将服务器 UTC 时间转换为本地时间?

How to convert Server UTC Time to local time in Swift 4?

我已经尝试了一些类似的问题和答案,但仍然没有用。 我正在尝试转换 2019-09-30T09:10:32.537244Z

func serverToLocal(date:String) -> Date? {
    let dateFormatter = DateFormatter()
    dateFormatter.dateFormat = "yyyy-MM-ddTHH:mm:ss.SSSSSSZ"
    dateFormatter.timeZone = TimeZone(abbreviation: "UTC")
    let localDate = dateFormatter.date(from: date)

    return localDate
}

以上方法始终return 无。我的日期格式有什么问题?

显然,关键问题是 T.

周围没有引号

但您可能不希望每次调用此例程时都实例化一个新的日期格式化程序(因为这是众所周知的计算量大的过程)。所以你应该将你的日期格式化程序保存为 属性。这样您就不需要为每个要转换为 Date 的字符串实例化一个新的格式化程序。同样,此格式化程序可用于将日期转换回 2019-09-30T09:10:32.537244Z.

格式的字符串

因此,与其他地方提供的建议相反,我建议设置格式化程序的timeZone。从字符串转换为日期时不需要它(因为日期字符串包含时区限定符),但是当从日期返回到字符串时,您确实需要日期格式化程序来指定时区,或者日期将在设备的本地时区。这样,您的格式化程序仍然适用于将字符串转换为日期以及返回字符串。

同样,我建议将 Z 替换为 ZZZZZX。同样,这仅在日期格式化程序也用于将日期转换回字符串时才重要(否则,生成的字符串将包含 +0000 而不是 Z )。最重要的是,我发现使用 X/ZZZZZ 意味着我永远不必担心它,它在格式化程序将 2019-09-30T09:10:32.537244Z 转换为 Date 对象时起作用,或者反之亦然。

因此:

let iso8601DateFormatter: DateFormatter = {
    let formatter = DateFormatter()
    formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSSSSX"
    formatter.timeZone = TimeZone(secondsFromGMT: 0)
    formatter.locale = Locale(identifier: "en_US_POSIX")
    return formatter
}()

func serverToLocal(string: String) -> Date? {
    return iso8601DateFormatter.date(from: string)
}

func localToServer(date: Date) -> String {
    return iso8601DateFormatter.string(from: date)
}

顺便说一下,你说的是“服务器”日期字符串。您是否通过 JSON 交换数据?如果您使用 JSONEncoderJSONDecoder 解析 JSON 中的字符串,您可以在编码器的 dateEncodingStrategy or the decoder's dateDecodingStrategy 中使用格式化程序。这样,您的基础模型对象就可以只是 Date 属性,而 JSON encoder/decoder 将负责将 JSON 中的日期字符串转换为 Date对象(和背面)。然后你根本不需要这些 serverToLocallocalToServer 方法。


FWIW,有关引用 T、设置语言环境等的更多信息,请参阅 Apple 的 Technical Q&A 1480。这是一篇旧文档,主要关注 Objective-C,但它讨论的是此处概述的概念。