Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to convert date like \/Date(1440156888750-0700)\/ to something that Swift can handle?

so in my app, I need to deal with date like \/Date(1440156888750-0700)\/, i think the first part stands for the seconds from Jan 1st, 1970 and the second part is the timezone. I don't know how to handle data like this and display it the way we all understand in Xcode 7 using Swift 2?

like image 889
WhiteRice Avatar asked Dec 24 '22 13:12

WhiteRice


1 Answers

(The previous version of this answer was actually wrong, it did not handle the time zone correctly.)

According to Stand-Alone JSON Serialization:

DateTime values appear as JSON strings in the form of "/Date(700000+0500)/", where the first number (700000 in the example provided) is the number of milliseconds in the GMT time zone, regular (non-daylight savings) time since midnight, January 1, 1970. The number may be negative to represent earlier times. The part that consists of "+0500" in the example is optional and indicates that the time is of the Local kind - that is, should be converted to the local time zone on deserialization. If it is absent, the time is deserialized as Utc. The actual number ("0500" in this example) and its sign (+ or -) are ignored.

and Use JSON.NET to parse json date of format Date(epochTime-offset)

... In this [screwy format][1], the timestamp portion is still based solely on UTC. The offset is extra information. It doesn't change the timestamp. You can give a different offset, or omit it entirely and it's still the same moment in time.

the first number in \/Date(1440156888750-0700)\/ is the number of milliseconds since the "epoch" January 1, 1970 GMT, and the time zone part -0700 must simply be ignored.

Here is a Swift 5 extension method for Date which checks the validity of the string with a regular expression (accepting both \/Date(...)\/ and /Date(...)/, with or without a time zone specification) and converts the given number of milliseconds to a Date:

extension Date {
    init?(jsonDate: String) {

        let pattern = #"\\?/Date\((\d+)([+-]\d{4})?\)\\?/"#
        let regex = try! NSRegularExpression(pattern: pattern)
        guard let match = regex.firstMatch(in: jsonDate, range: NSRange(jsonDate.startIndex..., in: jsonDate)) else {
            return nil
        }

        // Extract milliseconds:
        let dateString = jsonDate[Range(match.range(at: 1), in: jsonDate)!]
        // Convert to UNIX timestamp in seconds:
        let timeStamp = Double(dateString)! / 1000.0
        // Create Date from timestamp:
        self.init(timeIntervalSince1970: timeStamp)
    }
}

Example:

let jsonDate = "\\/Date(1440156888750-0700)\\/"
print("JSON Date:", jsonDate)

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

Output:

JSON Date: \/Date(1440156888750-0700)\/
Date: 2015-08-21 11:34:48 +0000

(Versions for Swift 3 and Swift 4 can be found in the edit history.)

like image 139
Martin R Avatar answered Dec 27 '22 12:12

Martin R