簡體   English   中英

DateFormatter 在解碼 JSON 時為有效字符串返回 nil

[英]DateFormatter returning nil for valid String when decoding JSON

我正在嘗試在 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

關鍵的觀察是確保您使用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"

因此,如果您想要標准"2019-11-12T21:37:39Z" ,請使用ZZZZZ ,但如果您想要"2019-11-12T21:37:39+00:00" ,請使用xxxxx


順便說一句,有關ZZZZZZXxxxxx等所有不同排列的更多信息,請參閱日期格式模式中表格的時區部分。


當我構建並運行應用程序並在初始化日期后設置斷點時,該值始終為nil

順便說一句,始終print (或 lldb 中的PO )該值。 有時,Xcode 中的檢查員 window 會不同步並顯示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)
}
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
}

用法- 字符串格式的 api 響應日期

let time1 = "2019-11-08T01:26:45+00:00"
print(convertDateString(dateString: time1,dateFormat: "EEEE, MMM d, yyyy"))

OUTPUT --->>> 2019 年 11 月 8 日星期五

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM