swift 快速获取服务器时间

ecbunoof  于 2023-02-21  发布在  Swift
关注(0)|答案(3)|浏览(243)

是否有办法获取服务器时间以用于swift。我想设置一个基于服务器的静态时间。这样,即使用户更改时区和日期,也不会产生影响,并且视图控制器上显示的时间将是基于服务器的时间,而不是NSDate

let today = NSDate()
 println(today)

目前上述代码,改变日期和时间,如果它在电话设置中改变.我也在我的代码中使用解析.有没有一种方法从解析获得服务器时间.

5n0oy7gb

5n0oy7gb1#

基于这个链接https://github.com/freak4pc/NSDate-ServerDate,我写了swift的代码,尝试和测试,它工作。

override func viewDidLoad() {
    super.viewDidLoad()

    //call ServerTimeReturn function

    serverTimeReturn { (getResDate) -> Void in
        var dFormatter = NSDateFormatter()
        dFormatter.dateStyle = NSDateFormatterStyle.LongStyle
        dFormatter.timeStyle = NSDateFormatterStyle.LongStyle
        dFormatter.timeZone = NSTimeZone(abbreviation: "GMT")
        var dateGet = dFormatter.stringFromDate(getResDate)

        println("Formatted Time : \(dateGet)")
    }

        }

    func serverTimeReturn(completionHandler:(getResDate: NSDate!) -> Void){

    let url = NSURL(string: "http://www.google.com")      
    let task = NSURLSession.sharedSession().dataTaskWithURL(url!) {(data, response, error) in
        let httpResponse = response as? NSHTTPURLResponse
        if let contentType = httpResponse!.allHeaderFields["Date"] as? String {

            var dFormatter = NSDateFormatter()
            dFormatter.dateFormat = "EEE, dd MMM yyyy HH:mm:ss z"
            var serverTime = dFormatter.dateFromString(contentType)
            completionHandler(getResDate: serverTime)
        }
    }

    task.resume()
}
blpfk2vs

blpfk2vs2#

由于网络呼叫是昂贵的,
你不应该在每次需要得到正确的日期时间时都进行相同的网络调用。
当从某个服务器获取时间时,将本地和服务器之间的时差存储在某个地方,并使用它来获取校正的日期。

示例

private var timeGap: TimeInterval = 0
private var referenceDate = Date() {
    didSet { timeGap = Date().distance(to: referenceDate) }
}

var correctedDate: Date {
    let possibleDate = Date()
    let ignorableNetworkDelay: TimeInterval = 2

    guard abs(timeGap) > ignorableNetworkDelay else { return possibleDate }
    return possibleDate.advanced(by: timeGap)
}

func setReferenceDate() {
    let url = URL(string: "https://www.google.com")

    URLSession.shared.dataTask(with: url!) { _, response, _ in
        let httpResponse = response as? HTTPURLResponse
        if let stringDate = httpResponse?.allHeaderFields["Date"] as? String {
            let formatter = DateFormatter()
            formatter.dateFormat = "EEE, dd MMM yyyy HH:mm:ss z"
            formatter.timeZone = TimeZone.current
            serverDate = formatter.date(from: stringDate) ?? Date()
        } else {
            print("getting reference date from web failed")
            referenceDate = Date()
        }
    }.resume()
}

这样,我就可以随时引用correctedDate,而不必担心成本,
并且只在需要更正日期时间时调用setReferenceDate()***。

  • (例如,当应用程序进入后台时)*
1hdlvixo

1hdlvixo3#

func getServerTimer(completion:@escaping (Date?)->()) {

    serverTimeReturn { date   -> Void in
        let dFormatter = DateFormatter()
        dFormatter.dateStyle = .long
        dFormatter.timeStyle = .long
        dFormatter.timeZone = TimeZone(abbreviation: "GMT")
        if let date = date {
            let dateGet = dFormatter.string(from: date)
            completion(date)
            print("Formatted Time : \(dateGet)")
        } else {
            completion(nil)
        }
    }

}

func serverTimeReturn(completionHandler:@escaping (_ getResDate: Date?) -> Void) {

    let url = NSURL(string: "https://www.google.com")
    let task = URLSession.shared.dataTask(with: url! as URL) {(data, response, error) in
        let httpResponse = response as? HTTPURLResponse
        if let contentType = httpResponse!.allHeaderFields["Date"] as? String {

            let dFormatter = DateFormatter()
            dFormatter.dateFormat = "EEE, dd MMM yyyy HH:mm:ss z"
            dFormatter.locale = Locale(identifier: "en-US")
            if let serverTime = dFormatter.date(from: contentType) {
                completionHandler(serverTime)
            } else {
                completionHandler(nil)
            }
        }
    }

    task.resume()
}

相关问题