我碰到一个返回以下格式的字符串的Web服务:

“yyyy-MM-dd'T'HH:mmZ”

它与标准UTC格式非常接近,但最后没有ss。我的问题是我的dateFormatter总是返回nil ...并且我试图确保语言环境和其他所有设置都正确。

这是一个实际字符串的示例:
2019-12-26T00:00Z
这是创建DF的代码:

extension DateFormatter {
    @objc static func defaultDateFormat(_ format: String) -> DateFormatter {
        let formatter = DateFormatter()
        formatter.locale = Locale(identifier: "US")
        formatter.dateFormat = format
        return formatter
    }

    func date(from string: String?) -> Date? {
        if let string = string {
            return self.date(from: string)
        } else {
            return nil
        }
    }

    func string(fromOptional date: Date?) -> String? {
        if let date = date {
            return self.string(from: date)
        } else {
            return nil
        }
    }

    func string(fromOptional date: Date?, defaultStr: String) -> String {
        return self.string(fromOptional: date) ?? defaultStr
    }
}

let df = DateFormatter.defaultDateFormat("yyyy-MM-dd'T'HH:mmZ")
let date: Date? = df.date(from: __dateString__) // always nil

最佳答案

一些观察:

  • 您想使用en_US_POSIX的语言环境,这是一个始终适用于ISO 8601 / RFC 3339日期字符串的不变语言环境。参见Technical Q&A 1480
  • 如果要使用此格式化程序将日期转换回类似2019-12-26T00:00Z的字符串,则需要:
  • 在格式字符串中使用X(或ZZZZZXXXXX),而不是Z(请参见Date Format Patterns表中的“区域”部分),您将看到如何解释这些不同的时区模式,例如ZZZZZZX。 );和
  • 设置格式化程序的timeZone以使用Zulu / GMT / UTC。

  • 从而:
    @objc static func defaultDateFormat(_ format: String) -> DateFormatter {
        let formatter = DateFormatter()
        formatter.locale = Locale(identifier: "en_US_POSIX")
        formatter.timeZone = TimeZone(secondsFromGMT: 0)
        formatter.dateFormat = format
        return formatter
    }
    


    let df = DateFormatter.defaultDateFormat("yyyy-MM-dd'T'HH:mmX")
    let date = df.date(from: "2019-12-26T00:00Z")
    

    要么
    let string = df.string(from: Date())
    

    09-27 03:26
    查看更多