Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
573 views
in Technique[技术] by (71.8m points)

ios - 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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

(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.)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...