Parsing JSON (date) to Swift
Solution 1
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")
}
Solution 2
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!
![Admin](/assets/logo_square_200-5d0d61d6853298bd2a4fe063103715b4daf2819fc21225efa21dfb93e61952ea.png)
Admin
Updated on June 12, 2022Comments
-
Admin about 2 years
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) /". How do I convert this into NSDate? In Swift, please, I´ve tested examples with Objective-C, without success.
-
Admin over 9 yearsAnd how I get timespan of this variable?
-
JAHelia over 7 years@Martin this extension fails for a value like: "/Date(1479119050805+0300)/" because the Double init method of milliseconds cannot return a double for the value of 1479119050805+0300 due to the plus sign, if you manage to handle this case please share your code here
-
Martin R over 7 years@JAHelia: Have a look at stackoverflow.com/a/33166980/1187415 for a newer version which reads JSON dates with or without timezone offset.
-
Martin R over 6 yearsThe question is about parsing a string like
"/Date(1420420409680)/"