[英]Convert UNIX time from json import (swift struct) to date as string and populate table
我有一個導入到我的項目中的json文件( https://api.myjson.com/bins/ywv0k )。 json屬性被解碼並存儲在結構類“ News”中,該結構類具有與json文件相同的屬性。
在第二步中,我從結構類“ News”中填充帶有字符串屬性“ timestamp”的表,這實際上是UNIX時間。
我現在的問題是我迷失了如何將此UNIX時間更改為格式為“ dd / mm / yy HH:mm:ss”的字符串,因為在嘗試放置函數時出現錯誤
let date = NSDate(timeIntervalSince1970: timestamp) //error since timestamp is currently defined as string. If I make it a long variable, I cannot populate the table with it any more, since the label requires a text with string format.
let dayTimePeriodFormatter = NSDateFormatter()
dayTimePeriodFormatter.dateFormat = "dd/mm/yy HH:mm:ss"
let dateString = dayTimePeriodFormatter.stringFromDate(date)
進入do-encoding-loop以及將其放入此表函數時:func tableView(_ tableView:UITableView,cellForRowAt indexPath:IndexPath)-> UITableViewCell。
斯威夫特4
import UIKit
// structure from json file
struct News: Codable{
let type: String
let timestamp: String // UNIX format, eg. "1531294146340"
let title: String
let message: String
}
class HomeVC: BaseViewController, UITableViewDelegate, UITableViewDataSource {
var myNewsItems: [News] = []
@IBOutlet weak var myNewTableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
let nibName = UINib(nibName: "CustomTableViewCell", bundle: nil)
myNewTableView.register(nibName, forCellReuseIdentifier: "tableViewCell")
// JSON Decoding
let url=URL(string:"https://api.myjson.com/bins/ywv0k")
let session = URLSession.shared
let task = session.dataTask(with: url!) { (data, response, error) in
guard let data = data else { return }
do {
let myNewsS = try
JSONDecoder().decode([News].self, from: data)
print(myNewsS)
self.myNewsItems = myNewsS
DispatchQueue.main.async {
self.myNewTableView.reloadData()
}
} catch let jsonErr {
}
}
task.resume()
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return myNewsItems.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "tableViewCell", for: indexPath) as!
CustomTableViewCell
// populate table with json content
cell.commonInit(timestamp: myNewsItems[indexPath.row].timestamp, message: myNewsItems[indexPath.row].message)
return cell
}
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
cell.backgroundColor = UIColor(white: 1, alpha: 0.5)
}
}
首先日期格式錯誤。 必須為"dd/MM/yy HH:mm:ss"
如果您負責JSON,則最有效的解決方案是將timestamp
的值發送為Double
。 然后就足夠聲明timestamp
let timestamp: Date // UNIX format, eg. 1531294146340
並添加日期解碼策略
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .millisecondsSince1970
另一個解決方案是將日期轉換代碼放入struct
struct News: Codable{
let type: String
let timestamp: String // UNIX format, eg. "1531294146340"
let title: String
let message: String
enum CodingKeys: String, CodingKey { case type, timestamp, title, message}
let dateFormatter : DateFormatter = {
let formatter = DateFormatter()
formatter.dateFormat = "dd/MM/yy HH:mm:ss"
return formatter
}()
var dateString : String {
let timeInterval = TimeInterval(timestamp)!
let date = Date(timeIntervalSince1970: timeInterval / 1000)
return dateFormatter.string(from:date)
}
}
計算的屬性dateString
包含日期字符串。
此外,您可以將type
聲明為枚舉
enum Type : String, Codable {
case organizational, planning
}
struct News: Codable{
let type: Type
...
您應該能夠將時間戳轉換為日期,然后將其格式化為特定格式,然后轉換回String以顯示在UILabel上。 查看以下內容是否有幫助
func string(from timestamp: String) -> String {
if let timeInterval = TimeInterval(timestamp) {
let date = Date(timeIntervalSince1970: timeInterval)
let formatter = DateFormatter()
formatter.dateFormat = "dd/MM/yy HH:mm:ss"
return formatter.string(from: date)
}
return "" //return empty if somehow the timestamp conversion to TimeInterval (Double) fails
}
1)作為第一個建議,不要出於任何原因將日期存儲為字符串。
(Apple表示使用非常基本的類型...因此,對於UnixTimestamp或NSDate使用64位。.更加靈活,例如執行計算,差異,本地化等等...(以及更好的內存使用。.(Ints甚至不使用ARC ...))
(並且對字段使用可選。...更加安全。)
2)因此,請使用擴展名另存為日期(例如)
讓我們從一個int unixTimestamp開始:
(我為控制器添加了完整的示例...)
//
// ViewController.swift
// sampleDate
//
// Created by ing.conti on 16/08/2018.
// Copyright © 2018 com.ingconti. All rights reserved.
//
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
//sample with int...
if let dm =
// Thursday, January 1, 2015 12:00:00 AM GMT+01:00
(1420066800000/1000).fromUnixTimeStamp(){
// note: usual timestamp from server come with milliseincods..
//now You get a date... use and format!
print(dm.description)
}
let testString = "1420066800"
if let n = Int(testString), let dm = n.fromUnixTimeStamp(){
print(dm.description)
}
}
}
extension Int {
func fromUnixTimeStamp() -> Date? {
let date = Date(timeIntervalSince1970: TimeInterval(self))
return date
}
}
因此請使用擴展名並更改您的使用日期。
最后一點:codable很好,但不適用於“邊緣情況”,蘋果在“ Reflecting on Reflection”( https://developer.apple.com/swift/blog/?id=37 )中說,有時寫得更好手動解析器...用於一小段JSON。
因此,例如使用:
(我改寫了你的課...)
typealias Dict = [String : Any]
struct News{
let type: String?
// NO! let timestamp: String // UNIX format, eg. "1531294146340"
let timestamp: Date?
let title: String?
let message: String?
init?(dict : Dict?) {
guard let d = dict else{
return nil
}
if let s = d["timestamp"] as? String, let n = Int(s) {
timestamp = n.fromUnixTimeStamp()
}else{
timestamp = nil // or other "default" ..
}
// go on parsing... other fields..
if let s = d["type"] as? String{
type = s
}else{
type = nil // or other "default" ..
}
if let s = d["title"] as? String {
title = s
}
else{
title = nil // or other "default" ..
}
if let s = d["message"] as? String {
message = s
}else{
message = nil // or other "default" ..
}
}
}
因此以這種方式使用:
...
let new = News(dict: dict)
我通常以這種方式提取數據形式的JSON:
...
guard let json = try? JSONSerialization.jsonObject(with: data, options: []) as? Dict
else{
return
}
guard let dict = json else{
return
}
..
let new = News(dict: dict)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.