【问题标题】:Parsing JSON (date) to Swift将 JSON(日期)解析为 Swift
【发布时间】:2015-01-12 18:12:07
【问题描述】:

我的 Swift 应用程序中有一个返回 JSON,并且有一个返回日期的字段。当我参考这些数据时,代码给了我类似“/日期(1420420409680)/”的信息。如何将其转换为 NSDate?请在 Swift 中使用 Objective-C 测试示例,但没有成功。

【问题讨论】:

  • 这是一个普通的旧 UNIX 时间戳。
  • @HotLicks: ...仅以毫秒为单位(或者它会在 46981 年 :)
  • @MartinR - 是的,您可以通过前导“14”识别它,然后您必须通过计算数字来确定它是秒、毫秒还是微秒。 (在一种情况下,我遇到的甚至是 10 纳秒。)

标签: ios json parsing swift


【解决方案1】:

这看起来与 Microsoft 的 ASP.NET AJAX 使用的日期的 JSON 编码非常相似,后者 描述在An Introduction to JavaScript Object Notation (JSON) in JavaScript and .NET:

例如,Microsoft 的 ASP.NET AJAX 既不使用上述描述的 公约。相反,它将 .NET DateTime 值编码为 JSON 字符串, 其中字符串的内容是 /Date(ticks)/ 并且在哪里打勾 表示自纪元 (UTC) 以来的毫秒数。所以在 1989 年 11 月 29 日, 凌晨 4:55:30,UTC 编码为“\/Date(628318530718)\/”。

唯一的区别是你的格式是/Date(ticks)/ 而不是\/Date(ticks)\/

您必须提取括号之间的数字。除以 1000 给出自 1970 年 1 月 1 日以来的秒数。

以下代码显示了如何做到这一点。它被实现为 NSDate 的“失败的便利初始化程序”:

extension NSDate {
    convenience init?(jsonDate: String) {

        let prefix = "/Date("
        let suffix = ")/"
        // Check for correct format:
        if jsonDate.hasPrefix(prefix) && jsonDate.hasSuffix(suffix) {
            // Extract the number as a string:
            let from = jsonDate.startIndex.advancedBy(prefix.characters.count)
            let to = jsonDate.endIndex.advancedBy(-suffix.characters.count)
            // Convert milliseconds to double
            guard let milliSeconds = Double(jsonDate[from ..< to]) else {
                return nil
            }
            // Create NSDate with this UNIX timestamp
            self.init(timeIntervalSince1970: milliSeconds/1000.0)
        } else {
            return nil
        }
    }
}

示例用法(使用您的日期字符串):

if let theDate = NSDate(jsonDate: "/Date(1420420409680)/") {
    print(theDate)
} else {
    print("wrong format")
}

这给出了输出

2015-01-05 01:13:29 +0000

Swift 3 (Xcode 8) 更新:

extension Date {
    init?(jsonDate: String) {

        let prefix = "/Date("
        let suffix = ")/"

        // Check for correct format:
        guard jsonDate.hasPrefix(prefix) && jsonDate.hasSuffix(suffix) else { return nil }

        // Extract the number as a string:
        let from = jsonDate.index(jsonDate.startIndex, offsetBy: prefix.characters.count)
        let to = jsonDate.index(jsonDate.endIndex, offsetBy: -suffix.characters.count)

        // Convert milliseconds to double
        guard let milliSeconds = Double(jsonDate[from ..< to]) else { return nil }

        // Create NSDate with this UNIX timestamp
        self.init(timeIntervalSince1970: milliSeconds/1000.0)
    }
}

例子:

if let theDate = Date(jsonDate: "/Date(1420420409680)/") {
    print(theDate)
} else {
    print("wrong format")
}

【讨论】:

  • @Martin 此扩展因以下值而失败:“/Date(1479119050805+0300)/”,因为毫秒的 Double init 方法无法返回值 1479119050805+0300 的双精度值,因为加号签名,如果您设法处理此案例,请在此处分享您的代码
  • @JAHelia:查看stackoverflow.com/a/33166980/1187415 的更新版本,它可以读取带有或不带有时区偏移的 JSON 日期。
【解决方案2】:

添加到其他人提供的内容,只需在下面的类中创建实用方法:

  func dateFromStringConverter(date: String)-> NSDate? {
    //Create Date Formatter
    let dateFormatter = NSDateFormatter()
    //Specify Format of String to Parse
    dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ" //or you can use "yyyy-MM-dd'T'HH:mm:ssX"
    //Parse into NSDate
    let dateFromString : NSDate = dateFormatter.dateFromString(date)!

    return dateFromString
}

然后你就可以在你成功返回、解析后的 JSON 对象中调用这个方法,如下所示:

//Parse the date
 guard let datePhotoWasTaken = itemDictionary["date_taken"] as? String else {return}
     YourClassModel.dateTakenProperty = self.dateFromStringConverter(datePhotoWasTaken)

或者您可以完全忽略上面的实用方法和调用者代码,只需执行以下操作:

//Parse the date
 guard let datePhotoWasTaken = itemDictionary["date_taken"] as? NSString else {return}
     YourClassModel.dateTakenProperty = NSDate(timeIntervalSince1970: datePhotoWasTaken.doubleValue)

这应该行得通!

【讨论】:

  • 问题是关于解析像"/Date(1420420409680)/"这样的字符串
【解决方案3】:

它看起来像一个 UNIX 时间戳:01/12/2015 @ 6:14pm (UTC) [根据 http://www.unixtimestamp.com/index.php]

您可以使用构造函数 NSDate(timeIntervalSince1970: unixTimestamp) 将其转换为 NSDate 对象

【讨论】:

  • 我如何获得这个变量的时间跨度?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-26
相关资源
最近更新 更多