使用Swift Decodable解析任意格式的JSON日期 [英] Parsing arbitrary format JSON date with Swift Decodable
问题描述
我正在尝试将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屋!