繁体   English   中英

Swift ISO 8601 日期格式

[英]Swift ISO 8601 date formatting

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

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

我想在文本 label 中将日期字符串显示为“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
}

将您的日期传递给此

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

    let val = dateFormatterPrint.string(from: "pass your date")
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))

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

您可以使用扩展来将日期转换为您想要的格式。

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")

一般来说,如果手动将1993-07-20T09:44:18.674Z转换为Date ,我们会使用ISO8601DateFormatter

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

在这种方法中,它为我们处理时区和语言环境。


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

但这不能使用ISO8601DateFormatter 我们必须使用DateFormatter ,其dateFormat"yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ"localeLocale(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)

请参阅DateFormatter 文档的“使用固定格式日期表示”部分。


然后,对于您的 UI 格式化程序,如果您绝对想要dd-MMM-yyyy格式,您将有一个单独的格式化程序,例如:

let formatter = DateFormatter()
formatter.dateFormat = "dd-MMM-yyyy"

请注意,对于这个 UI 日期格式化程序,我们不设置localetimeZone ,而是让它使用设备的当前默认值。

话虽如此,我们通常希望避免对 UI 中显示的日期字符串使用dateFormat 我们通常更喜欢dateStyle ,它以用户喜欢的格式显示日期:

let formatter = DateFormatter()
formatter.dateStyle = .medium

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

请参阅上述DateFormatter 文档中的“使用用户可见的日期和时间表示”。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM