如何将date转换为\ / Date(1440156888750-0700)\ /到Swift可以处理的东西?
所以在我的应用程序中,我需要处理date,如\/Date(1440156888750-0700)\/
,我认为第一部分代表从1970年1月1日秒,第二部分是时区。 我不知道如何处理这样的数据,并使用Swift 2以Xcode 7的方式来显示它。
(这个答案以前的版本其实是错误的,它没有正确处理时区。)
根据独立的JSON序列化 :
date时间值以“/ Date(700000 + 0500)/”的forms显示为JSONstring,其中第一个数字(在提供的示例中为700000)是GMT时区中的毫秒数,常规(非夏令时)是1970年1月1日午夜以来的时间。这个数字可能是负数,代表早些时候。 示例中由“+0500”组成的部分是可选的,表示时间是Localtypes的,即在反序列化时应该转换为本地时区。 如果不存在,则将时间反序列化为Utc。 实际的数字(本例中为“0500”)及其符号(+或 – )被忽略。
并使用JSON.NET来parsing格式date(epochTime-offset)的jsondate
…在这个[screwy格式] [1]中,时间戳部分仍然完全基于UTC。 偏移量是额外的信息。 它不会更改时间戳。 你可以给出一个不同的偏移量,或者完全忽略这个偏移量,它仍然是相同的时间。
\/Date(1440156888750-0700)\/
中的第一个数字是自1970年1月1日GMT“时代”以来的毫秒数,时区部分-0700
必须简单忽略。
这是Date
的Swift 3扩展方法,用正则expression式检查string的有效性(接受\/Date(...)\/
和/Date(...)/
,有或没有时区指定)并将给定的毫秒数转换为Date
:
extension Date { init?(jsonDate: String) { let pattern = "\\\\?/Date\\((\\d+)(([+-]\\d{2})(\\d{2}))?\\)\\\\?/" let regex = try! NSRegularExpression(pattern: pattern) guard let match = regex.firstMatch(in: jsonDate, range: NSRange(location: 0, length: jsonDate.utf16.count)) else { return nil } // Extract milliseconds: let dateString = (jsonDate as NSString).substring(with: match.rangeAt(1)) // Convert to UNIX timestamp in seconds: let timeStamp = Double(dateString)! / 1000.0 // Create Date from timestamp: self.init(timeIntervalSince1970: timeStamp) } }
例:
let jsonDate = "\\/Date(1440156888750-0700)\\/" print("JSON Date:", jsonDate) if let theDate = Date(jsonDate: jsonDate) { print("Date:", theDate) } else { print("wrong format") }
输出:
JSONdate:\ / Date(1440156888750-0700)\ / date:2015-08-21 11:34:48 +0000
Swift 4的更新:
extension Date { init?(jsonDate: String) { let pattern = "\\\\?/Date\\((\\d+)(([+-]\\d{2})(\\d{2}))?\\)\\\\?/" 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.substring(with: 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) } }
经过一些实验后,我想出了以下解决scheme:
let dx = "/Date(1440156888750-0700)/" let timestamp = (dx as NSString).substringWithRange(NSRange(location: 6,length: 13)) let timezone = (dx as NSString).substringWithRange(NSRange(location: 19,length: 5)) let dateIntermediate = NSDate(timeIntervalSince1970: Double(timestamp)! / 1000) let outp = NSDateFormatter() outp.dateFormat = "dd.MM.yyyy hh:mm::ssSSS" outp.timeZone = NSTimeZone(forSecondsFromGMT: 0) let input = outp.stringFromDate(dateIntermediate) + " " + timezone let inp = NSDateFormatter() inp.dateFormat = "dd.MM.yyyy hh:mm::ssSSS Z" let finalDate = inp.dateFromString(input) print(finalDate)
让我解释:
- 我们从原始string中提取毫秒时间戳和时区
- 我们从时间戳创build一个date,以便能够将其分成不同的组件
- 我们以更加标准的方式输出date(而不是时间戳),并将以前提取的时区附加到该string
- 然后我们再读取这个string,并从中parsing一个date
注意
作为@ Phoen1xUK提到的时间戳可能有不同的长度比13位数字。 你可以通过去除/Date(
和)/
然后在-
(或+
)之前分割string来处理这种情况。