Parsing JSON (date) to Swift

后端 未结 3 803
爱一瞬间的悲伤
爱一瞬间的悲伤 2020-12-09 22:33

I have a return JSON in my application in Swift, and have a field that returns me a date. When I refer to this data, the code gives me something like \"/ Date (1420420409680

相关标签:
3条回答
  • 2020-12-09 22:50

    That looks very similar to the JSON encoding for a date as used by Microsoft's ASP.NET AJAX, which is described in An Introduction to JavaScript Object Notation (JSON) in JavaScript and .NET:

    For example, Microsoft's ASP.NET AJAX uses neither of the described conventions. Rather, it encodes .NET DateTime values as a JSON string, where the content of the string is /Date(ticks)/ and where ticks represents milliseconds since epoch (UTC). So November 29, 1989, 4:55:30 AM, in UTC is encoded as "\/Date(628318530718)\/".

    The only difference is that you have the format /Date(ticks)/ and not \/Date(ticks)\/.

    You have to extract the number between the parentheses. Dividing that by 1000 gives the number in seconds since 1 January 1970.

    The following code shows how that could be done. It is implemented as a "failable convenience initializer" for 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
            }
        }
    }
    

    Example usage (with your date string):

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

    This gives the output

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

    Update for 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)
        }
    }
    

    Example:

    if let theDate = Date(jsonDate: "/Date(1420420409680)/") {
        print(theDate)
    } else {
        print("wrong format")
    }
    
    0 讨论(0)
  • 2020-12-09 23:00

    Adding onto what the others have provided, simply create utility method in your class below:

      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
    }
    

    Then you can call this method in your successfully returned, parsed JSON object, like below:

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

    Or you can ignore the utility method and the caller code above entirely and simply do this:

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

    And that should work!

    0 讨论(0)
  • 2020-12-09 23:06

    It looks like an UNIX Timestamp: 01/12/2015 @ 6:14pm (UTC) [According to http://www.unixtimestamp.com/index.php ]

    You can convert it to an NSDate object using the constructor NSDate(timeIntervalSince1970: unixTimestamp)

    0 讨论(0)
提交回复
热议问题