让这个 DateFormatter 工作需要什么?

What is needed to get this DateFormatter working?

我无法让日期格式化程序在给定字符串时输出日期。我使用的代码如下:

        let formatter = DateFormatter()

    formatter.locale = Locale(identifier: "en_GB")
    formatter.setLocalizedDateFormatFromTemplate("yyyy-MM-dd'T'HH:mm:ss'Z'")

    if let date = formatter.date(from: string){
        return date
    }else{
        print("Fail: " + string)
        print("Form: yyyy-MM-dd'T'HH:mm:ss'Z'")
        return Date(timeIntervalSince1970: TimeInterval(0))
    }

我使用的日期是“2017-03-22T17:09:16Z”。但是,返回的结果总是 nil(运行失败循环)。我已经尝试了 DateFormatter 文档中的两个版本(这个和 "Working With Fixed Format Date Representations" 部分)。

这个字符串应该是有效的,但它不起作用。该字符串源自 ascii 格式的字节数组,使用适当的 init 函数从 String 转换而来。

问题是,我错过了什么?

您使用了错误的 DateFormatter 函数。 它应该是 setter 的 dateFormat

formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss'Z'"

应该 删除 Z 之间的 '。因为 "2017-03-22T17:09:16Z" 将与硬编码的 'Z' 一起使用,但不会与 "2017-03-22T17:09:16+02:00".

一起使用

但是,如果您设置:

formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ"

它可以理解任何时区

几个问题:

  1. 不要使用setLocalizedDateFormatFromTemplate。这是为了在 UI 中显示本地化的日期字符串。但是你需要一个文字日期字符串。请改用 dateFormat

  2. 不要使用 en_GB 语言环境。使用 en_US_POSIX。见苹果 Technical Q&A 1480.

  3. 如果你要查找文字 Z(用引号括起来),你必须将格式化程序的 timeZone 设置为 GMT/UTC/Zulu,也。或者,更好的是,只使用不带引号的 Z yyyy-MM-dd'T'HH:mm:ssZ,这将正确地将输入字符串中的 Z 解释为 GMT 时间字符串的指示符。问题中所写的代码不会正确调整时区。

因此:

let formatter = DateFormatter()

formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ"

if let date = formatter.date(from: string) {
    return date
} else {
    ...
}

顺便说一句,在 iOS 10 和 macOS 10.12 中引入的 ISO8601DateFormatter 让您摆脱了对区域设置、时区和格式字符串的担忧。它为您解析 ISO 8601/RFC 3339 日期格式:

let formatter = ISO8601DateFormatter()

if let date = formatter.date(from: string) {
    return date
} else {
    ...
}