使用Swift Decodable解析任意格式的JSON日期 [英] Parsing arbitrary format JSON date with Swift Decodable

查看:181
本文介绍了使用Swift Decodable解析任意格式的JSON日期的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将JSON文档中的日期格式化为"mm-dd-yyyy"格式.我有以下数据:

I am attempting to format a date in a JSON document into the format "mm-dd-yyyy". I have the following data:

{"data":[{
    "id": 123,
    "url": "https://www.google.com",
    "title": "The Google link",
    "created_at": "2017-08-29T04:00:00.000Z",//date to format
    "sent": true,
    "alternative": "https://google.com",
    "things": [],
    "description": [
        "search",
        "lookup"
    ],
    "company": "Alphabet"
    }]}

这是我的结构:

struct Sitedata: Decodable{
    let data: [site]
}

struct site: Decodable {
    let id: Int
    let url: String
    let title: String
    let created_at: String
    let sent: Bool
    let alternative: String
    let things: [String]
    let description: [String]
    let company: String
}

     let sites = try JSONDecoder().decode(Sitedata.self, from: data)

我尝试了以下方法,但产生了nil:

I tried the following method but it produced nil:

func date(dateString: String){
    // var dateString = "14.01.2017T14:54:00"
    let format = "dd.MM.yyyy'T'HH:mm:ss"
    let date = Date()

    print("original String with date:               \(dateString)")
    print("date String() to Date():                 \(dateString.toDate(format: format)!)")
    print("date String() to formated date String(): \(dateString.toDateString(inputFormat: format, outputFormat: "dd MMMM")!)")
    print("format Date():                           \(date.toString(format: "dd MMM HH:mm")!)")
}

extension DateFormatter {

    convenience init (format: String) {
        self.init()
        dateFormat = format
        locale = Locale.current
    }
}

extension String {

    func toDate (format: String) -> Date? {
        return DateFormatter(format: format).date(from: self)
    }

    func toDateString (inputFormat: String, outputFormat:String) -> String? {
        if let date = toDate(format: inputFormat) {
            return DateFormatter(format: outputFormat).string(from: date)
        }
        return nil
    }
}

extension Date {

    func toString (format:String) -> String? {
        return DateFormatter(format: format).string(from: self)
    }
}


How would I be able to parse and then format this date to MM-dd-yyyy?

推荐答案

首先,遵循Swift命名约定:UpperCamelCase代表类名,lowerCamelCase代表变量名.其次,帮自己一个忙,将created_at设置为Date字段,这很明显.以后您可以省下很多头痛.

First, follow the Swift naming convention: UpperCamelCase for class name and lowerCamelCase for variable name. Second, do yourself a favor and make created_at a Date field, like it's clearly is. That will save you a ton of headache later on.

这是代码:

struct SiteData: Decodable{
    let data: [Site]
}

struct Site: Decodable {
    let id: Int
    let url: String
    let title: String
    let created_at: Date        // changed to Date
    let sent: Bool
    let alternative: String
    let things: [String]
    let description: [String]
    let company: String
}

let formatter = DateFormatter()
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"

let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .formatted(formatter)
let sites = try decoder.decode(SiteData.self, from: json)

现在,已经从JSON中将created_at解析为正确的Date,则可以根据需要设置其格式:

Now that created_at has been parsed from JSON as a proper Date, you can format it however you like:

let formatter2 = DateFormatter()
formatter2.dateFormat = "MM-dd-yyyy"
print(formatter2.string(from: sites.data[0].created_at))

请注意,创建DateFormatter的成本非常高,更改其dateFormat属性的成本甚至更高.如果必须将大量日期格式化为字符串(反之亦然),则只需创建一次日期格式化程序,然后继续重复使用它们即可.

Note that DateFormatter is quite expensive to create and changing its dateFormat property is even more so. If you have to format a lot of dates to strings (or vice versa), create the date formatters only once and keep reusing them.

这篇关于使用Swift Decodable解析任意格式的JSON日期的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆