簡體   English   中英

按年-月的Swift JSON搜索日期格式?

[英]Swift JSON Search Date format by Year-month?

我正在使用Eodhistoricaldata.com的API來獲取每月的發行量。

https://eodhistoricaldata.com/api/eod/VTSMX?from=2017-09-01&api_token=xxxxxx&period=m&fmt=json

即使是月度數據,他們也會為結果指定第一個交易日期。 -01,-02,-03等

這意味着我不能使用通用日期-01。 因此YYYY-MM-01不起作用。

因此,我要么將所有日期更改為-01,要么僅按年份和月份進行搜索,例如“ 2017-10”

使用Swift 4和SwiftyJSON實現此目的的最佳方法是什么。

謝謝。

這是他們的數據。

[{"date":"2017-09-01","open":"61.9300","high":63.03,"low":"61.4400","close":63.03,"adjusted_close":61.6402,"volume":0},
{"date":"2017-10-02","open":"63.3400","high":"64.5300","low":"63.3400","close":64.39,"adjusted_close":62.9703,"volume":0},
{"date":"2017-11-01","open":"64.4400","high":66.35,"low":"64.0600","close":66.35,"adjusted_close":64.8872,"volume":0},
{"date":"2017-12-01","open":"66.2100","high":"67.3500","low":"65.7700","close":66.7,"adjusted_close":65.5322,"volume":0},
{"date":"2018-01-02","open":"67.2500","high":"71.4800","low":"67.2500","close":70.24,"adjusted_close":69.0102,"volume":0},
{"date":"2018-02-01","open":"70.2400","high":"70.2400","low":"64.4000","close":67.63,"adjusted_close":66.4458,"volume":0},
....
{"date":"2018-12-03","open":"69.5700","high":"69.5700","low":"58.1700","close":62.08,"adjusted_close":62.08,"volume":0}]

刪除SwiftyJSON並使用Decodable將JSON解析為一個結構。 解析日期是高度可定制的。 您可以添加自己的邏輯,該邏輯從日期字符串中提取年份和月份,並創建一個Date實例。

struct HistoricalData: Decodable {
    let date: Date
    let open, low, high : String
    let close, adjustedClose, volume : Double
}

...

let jsonString = """
[{"date":"2017-09-01","open":"61.9300","high":"63.03","low":"61.4400","close":63.03,"adjusted_close":61.6402,"volume":0},
{"date":"2017-10-02","open":"63.3400","high":"64.5300","low":"63.3400","close":64.39,"adjusted_close":62.9703,"volume":0},
{"date":"2017-11-01","open":"64.4400","high":"66.35","low":"64.0600","close":66.35,"adjusted_close":64.8872,"volume":0},
{"date":"2017-12-01","open":"66.2100","high":"67.3500","low":"65.7700","close":66.7,"adjusted_close":65.5322,"volume":0},
{"date":"2018-01-02","open":"67.2500","high":"71.4800","low":"67.2500","close":70.24,"adjusted_close":69.0102,"volume":0},
{"date":"2018-02-01","open":"70.2400","high":"70.2400","low":"64.4000","close":67.63,"adjusted_close":66.4458,"volume":0},
{"date":"2018-12-03","open":"69.5700","high":"69.5700","low":"58.1700","close":62.08,"adjusted_close":62.08,"volume":0}]
"""

let data = Data(jsonString.utf8)

let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
decoder.dateDecodingStrategy = .custom { decoder -> Date in
    let container = try decoder.singleValueContainer()
    let dateStr = try container.decode(String.self)
    let components = dateStr.components(separatedBy: "-")
    guard components.count > 2, let year = Int(components[0]), let month = Int(components[1]) else { throw DecodingError.dataCorruptedError(in: container, debugDescription: "Invalid date string") }
    return Calendar.current.date(from: DateComponents(year: year, month: month))!
}
do {
    let result = try decoder.decode([HistoricalData].self, from: data)
    print(result)
} catch { print(error) }

或者,您可以將字符串解碼為yyyy-MM格式,但是您必須編寫一個初始化程序並添加CodingKeys

struct HistoricalData: Decodable {
    let date: String
    let open, low, high : String
    let close, adjustedClose, volume : Double

    private enum CodingKeys : String, CodingKey {
       case date, open, low, high, close, adjustedClose, volume
    }

    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        let dateString = try container.decode(String.self, forKey: .date)
        guard let secondDashRange = dateString.range(of: "-", options: .backwards) else {
            throw DecodingError.dataCorruptedError(forKey: .date, in: container, debugDescription: "Invalid date string")
        }
        date = String(dateString[..<secondDashRange.lowerBound])
        open = try container.decode(String.self, forKey: .open)
        low = try container.decode(String.self, forKey: .low)
        high = try container.decode(String.self, forKey: .high)
        close = try container.decode(Double.self, forKey: .close)
        adjustedClose = try container.decode(Double.self, forKey: .adjustedClose)
        volume = try container.decode(Double.self, forKey: .volume)
    }

}

let data = Data(jsonString.utf8)

let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
do {
    let result = try decoder.decode([HistoricalData].self, from: data)
    print(result)
} catch { print(error) }

我能夠與API公司合作,利用電子歷史數據克服了這個問題。

現在,他們已經編寫了一個特殊的API以僅獲取最近的月度數據-因此不再需要編寫瘋狂的Json代碼。 現在對使用“句號= eom”的數據有特殊要求

jsonUrl =“ https://eodhistoricaldata.com/api/eod/(symbol).US?from=(beg)&to=(end)&api_token=(EOD_KEY)&period=eom&fmt=json

這確實使生活變得更好。 (浪費房子試圖克服他們的數據之后。)

暫無
暫無

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

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