Swift ISO 8601日期格式

时间:2019-11-22 04:10:33

标签: json swift xcode uikit

我正在对randomuser.me进行api调用,并获取一个包含(以及其他数据)的json文件:

“ dob”:{         “ date”:“ 1993-07-20T09:44:18.674Z”,         “年龄”:26       }

我想在文本标签中将日期字符串显示为“ dd-MMM-yyyy”,但无法弄清楚如何格式化字符串以实现此目的。

我尝试使用ISO8601DateFormatter将其转换为日期,然后再转换为字符串,但到目前为止还算不上运气。

有人可以帮忙吗?

func getUserData() {

    let config = URLSessionConfiguration.default
    config.urlCache = URLCache.shared
    let session = URLSession(configuration: config)

    let url = URL(string: "https://randomuser.me/api/?page=\(page)&results=20&seed=abc")!
    let urlRequest = URLRequest(url: url, cachePolicy: .returnCacheDataElseLoad, timeoutInterval: 15.0)
    let task = session.dataTask(with: urlRequest) { data, response, error in

        // Check for errors
        guard error == nil else {
            print ("error: \(error!)")
            return
        }
        // Check that data has been returned
        guard let content = data else {
            print("No data")
            return
        }

        do {
            let decoder = JSONDecoder()
            decoder.keyDecodingStrategy = .convertFromSnakeCase
            let fetchedData = try decoder.decode(User.self, from: content)

            for entry in fetchedData.results {
                self.usersData.append(entry)
            }

            DispatchQueue.main.async {
                self.tableView.reloadData()
            }

        } catch let err {
            print("Err", err)
        }
    }
    // Execute the HTTP request
    task.resume()
}

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "userInfoCell") as! UserInfoCell

    let user: Result

    if isFiltering {
        user = filteredData[indexPath.row]
    } else {
        user = usersData[indexPath.row]
    }

    cell.nameLabel.text = "\(user.name.first) \(user.name.last)"
    cell.dateOfBirthLabel.text = user.dob.date
    cell.genderLabel.text = user.gender.rawValue
    cell.thumbnailImage.loadImageFromURL(user.picture.thumbnail)

    return cell
}

4 个答案:

答案 0 :(得分:0)

将您的日期传递到此

    let dateFormatterPrint = DateFormatter()
    dateFormatterPrint.dateFormat = "dd-MM-yyyy"

    let val = dateFormatterPrint.string(from: "pass your date")

答案 1 :(得分:0)

import Foundation
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ"
let theDate = dateFormatter.date(from: "1993-07-20T09:44:18.674Z")!
let newDateFormater = DateFormatter()
newDateFormater.dateFormat = "dd-MMM-yyyy"
print(newDateFormater.string(from: theDate))

首先使用正确的日期格式将字符串转换为日期。然后使用所需的格式将其转换回字符串。

答案 2 :(得分:0)

您可以使用扩展名将日期转换为所需的格式。

var todayDate =“ 1993-07-20T09:44:18.674Z”

extension String {

    func convertDate(currentFormat: String, toFormat : String) ->  String {
        let dateFormator = DateFormatter()
        dateFormator.dateFormat = currentFormat
        let resultDate = dateFormator.date(from: self)
        dateFormator.dateFormat = toFormat
        return dateFormator.string(from: resultDate!)
    }
}

然后您可以像这样实现:

cell.dateOfBirthLabel.text = self.todayDate.convertDate(currentFormat:“ yyyy-MM-dd'T'HH:mm:ss.SSS'Z'”,toFormat:“ dd-MMM-yyyy”)

答案 3 :(得分:0)

通常,如果手动将1993-07-20T09:44:18.674Z转换为Date,我们将使用ISO8601DateFormatter

let formatter = ISO8601DateFormatter()
formatter.formatOptions.insert(.withFractionalSeconds)

通过这种方法,它可以为我们照顾时区和地区。


话虽如此,如果您使用JSONDecoder(及其下面概述的dateDecodingStrategy),那么我们应该定义模型对象以使用Date类型,而不是{{1 }}的所有日期。然后,我们告诉String使用特定的JSONDecoder为我们解码Date类型。

但是不能使用dateDecodingStrategy。我们必须使用ISO8601DateFormatter和{{1}的DateFormatterdateFormat的{​​{1}}的{​​{1}}:

"yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ"

请参见locale documentation的“使用固定格式的日期表示形式”部分。


然后,对于您的UI格式化程序,如果您绝对希望使用Locale(identifier: "en_US_POSIX")格式,则可以使用单独的格式化程序,例如:

let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ"
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.timeZone = TimeZone(secondsFromGMT: 0)  // this line only needed if you ever use the same formatter to convert `Date` objects back to strings, e.g. in `dateEncodingStrategy` of `JSONEncoder`

let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
decoder.dateDecodingStrategy = .formatted(formatter)

请注意,对于此UI日期格式程序,我们没有设置DateFormatterdd-MMM-yyyy,而是让其使用设备的当前默认值。

话虽如此,我们通常希望避免对UI中显示的日期字符串使用let formatter = DateFormatter() formatter.dateFormat = "dd-MMM-yyyy" 。通常,我们更喜欢locale,它以用户喜欢的格式显示日期:

timeZone

这样,美国用户将看到“ 2019年11月22日”,英国用户将看到“ 2019年11月22日”,法国用户将看到“ 11月22日”。 2019”。用户将以最习惯 的格式查看日期。

请参见上述dateFormat documentation中的“使用用户可见的日期和时间表示形式”。