DateFormatter在解码JSON时返回有效字符串的nil

时间:2019-11-12 21:27:39

标签: swift

我正在尝试在Swift中解码格式为2019-11-08T01:26:45+00:00的日期。不知道这是否相关,但这是从JSON提取的字符串。我尝试使用ISO8601DateFormatter,手动设置日期格式等,但是没有任何效果。 (response.timestamp的值为"2019-11-12T21:37:39+00:00",取自JSON。)

let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZZZZZ"
dateFormatter.locale = Locale.current
self.timestamp = dateFormatter.date(from: response.timestamp)

在我构建并运行应用程序并在初始化date后设置断点时,该值始终为nil

2 个答案:

答案 0 :(得分:1)

关键观察是确保您使用Working With Fixed Format Date Representations中概述的en_US_POSIX作为locale

let string = "2019-11-12T21:37:39+00:00"
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZZZZZ"
dateFormatter.locale = Locale(identifier: "en_US_POSIX")
let date = dateFormatter.date(from: string)

但是,值得注意的是,尽管此格式化程序将成功使用+00:00解释日期字符串,但是当将日期转换回字符串时,它将使用ISO 8601 / RFC 3339中常见的文字Z日期,例如"2019-11-12T21:37:39Z"。如果您确实希望结果字符串(如果您要将日期全部转换为字符串)使用+00:00约定,那么您将要使用xxxxx而不是ZZZZZ。您还需要为格式化程序指定一个timeZone

let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssxxxxx"
dateFormatter.locale = Locale(identifier: "en_US_POSIX")
dateFormatter.timeZone = TimeZone(secondsFromGMT: 0)
let string = dateFormatter.string(from: date)            // "2019-11-12T21:37:39+00:00"

因此,如果要使用标准ZZZZZ,请使用"2019-11-12T21:37:39Z",而如果要使用xxxxx,请使用"2019-11-12T21:37:39+00:00"


顺便说一句,有关ZZZZZZXxxxxx等所有不同排列的更多信息,请参见表的时区部分在Date Format Patterns


  

在构建和运行应用程序并在初始化日期之后设置断点时,该值始终为nil

顺便说一句,始终print(或lldb中的PO)值。有时,Xcode中的检查器窗口不同步,并在其中确实存在某些值时显示nil


正如jms所说,如果您使用的是JSONDecoder,则可能根本不应该使用date(from:)string(from:)。将您的媒体资源设置为Date类型,然后将您的解码器设置为dateDecodingStrategy

let json = """
    {"date" : "2019-11-12T21:37:39+00:00"}
    """
let data = json.data(using: .utf8)!

struct ResponseObject: Codable {
    let date: Date
}

let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .formatted(dateFormatter)

do {
    let object = try decoder.decode(ResponseObject.self, from: data)
} catch {
    print(error)
}

答案 1 :(得分:-1)

ALTER table ADD x_column DECIMAL(28,12)

用法-您的api响应日期(字符串格式)

func convertDateString(dateString:String,dateFormat:String = "") -> String {
    if dateString.isEmpty {
        return "" 
    }
    let dateFormatter = DateFormatter()
    let tempLocale = dateFormatter.locale // save locale temporarily
    dateFormatter.locale = Locale(identifier: "en_US_POSIX") // set locale to reliable US_POSIX en_US_POSIX
    dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss+s:s"
    let date = dateFormatter.date(from: dateString)!
    dateFormatter.dateFormat = dateFormat.isEmpty ? "dd-MM-yyyy" : dateFormat
    dateFormatter.locale = tempLocale // reset the locale
    let dateStr = dateFormatter.string(from: date)
    return dateStr
}

输出--- >>> 2019年11月8日星期五