iOS 客户端与服务端做时间同步


需求

我们做客户端的时候,有时会需要对客户端与服务器的时间进行同步,比如抢购活动、倒计时等。这时我们要考虑如何准备地与服务器的时间进行同步,同时防止用户本地的时间有误差时导致的问题。

分析

描述

为了实现以上需求,我们需要:

  1. 获取服务器某一时刻 A 的时间;

  2. 记录获取到时刻 A 时的本地时间 B

  3. 需要用到时间时,获取当前本地时间 C,当 C - B 作为时间间隔 D,则 A + D 则是当前服务器的时间。

实现

  1. 从上面的步骤,我们可以得到,要消除用户修改时间导致的影响,必须保证 BC 与系统时间无关;

  2. iOS 中正好有提供这样两个接口:

  3. 获取设备当前时间 Now,该值受系统时间影响,用户如果修改时间,值也会随着变化;

  4. 获取设备上次重启的时间 BootTime,该值受系统时间影响,用户如果修改时间,值也会随着变化;;

  5. 由上面 iOS 提供的两个接口,我们可以获取本地时间 BC:设备自上次重启后运行的时间(BootTime - Now),该值与系统时间无关;

代码实现

获取当前 Unix Time:

    static func now() -> Int {
        var now =  timeval()
        var tz = timezone()
        gettimeofday(&now, &tz)
        return now.tv_sec
    }

获取设备上次重启的 Unix Time:

    func boottime() -> Int {
        
        var mid = [CTL_KERN, KERN_BOOTTIME]
        var boottime = timeval()
        var size = MemoryLayout.size(ofValue: boottime)
        
        if sysctl(&mid, 2, &boottime, &size, nil, 0) != -1 {
            return boottime.tv_sec
        }
        return 0
    }

时间校准:

// 接口获取服务器时间处理
let serverTime = xxx                        // 获取到的服务器时间
let runTime0 = now() - boottime()           // 当前设备运行时间

// 需要用到时间时
let runTime1 = now() - boottime()           // 当前时刻设备运行时间
let currentTime = serverTime + (runTime1 - runTime0)    // 当前服务器时间

参考

iOS关于时间的处理

推荐阅读更多精彩内容

  • 风有情 行万余里 吹醒万物 不问归期 雨有情 飘浮不定 滋养大地 不计流失 只是 狂风暴雨 不知何需 强大蛮横 如...
    大清晨的小太阳阅读 41评论 0 1
  • (1) 接到妈妈的电话是下午四点多。 我刚刚结束一场培训,整个过程气氛很好,临场加入潜能激发的视频,恰到好处地湿润...
    若聆阅读 660评论 17 21
  • 本文系半撇私塾新媒体创意写作项目里程碑作品一。 1、 小时候,妈妈总是喜欢一边做事情的时候一边跟我解释这件事情是怎...
    桃花岛主sue阅读 58评论 1 0