与服务器时间同步问题

glzlaohuai 2013-04-16 11:43:01
做一个数据统计功能,客户端需要上报信息中有“时间”字段,因为客户端的时间是不可靠的,所以需要与服务器的时间做同步,开始考虑是这样做的:
1、本地保存需要上报的信息,信息中时间字段是客户端的时间
2、在向服务器上报时候,同时上报客户端当前时间(clientTime)
3、服务器在读取到统计信息以及clientTime以后,根据服务器当前时间(serverTime)与clientTime之间做比较,得出两端时间的差值,然后再对统计信息做一下处理就行了。

以上逻辑在用户不修改设备时间的情况下是没问题的,如果修改时间就不行了,然后考虑在修改时间以后看能不能获取到修改时间前后的差值,发现修改时间以后,系统会发送一个广播,但是这个广播中只携带了修改后的时间,而没有修改前的时间,所以前后的差值就得不到了。

现在想法是只能自己维护一个“时钟程序”,每隔一分钟就记录一下当前的timestamp,也就是用记录的timestamp来作为时间改变前的时间,当然了,记录间隔越短时间,计算的改变前后的差值也就越精确。

各位还有没有更好的办法?求教……
...全文
446 16 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
glzlaohuai 2013-05-16
  • 打赏
  • 举报
回复
引用 15 楼 CuGBabyBeaR 的回复:
不对 我错了 上边一楼当我没说
anyway, thanks so much for your attention
CuGBabyBeaR 2013-05-10
  • 打赏
  • 举报
回复
不对 我错了 上边一楼当我没说
CuGBabyBeaR 2013-05-10
  • 打赏
  • 举报
回复
对于你说的在reboot后 app启动之前进行的重启 对开机广播进行监听也无法解决这个问题 只能从其他方面解决 例如app启动的时候向服务器要一个时间之类
CuGBabyBeaR 2013-05-10
  • 打赏
  • 举报
回复
引用 12 楼 glzlaohuai 的回复:
[quote=引用 11 楼 CuGBabyBeaR 的回复:] 重启有也没关系啊... 主要目的是收到时间日期改变广播后计算出时间的变更值啊... elapsedRealtime只是个辅助工具而已啊
…… 1、app启动,记录下了timestamp以及elapsedRealtime 2、设备reboot 3、用户修改设备时间 ok,怎么计算[/quote] 在9楼已经说的很清楚了 换个说法再给你讲一遍 启动记录的timestamp 和elapsedRealtime 分别记为T1 和t1 收到系统通知 再次获取timestamp和elapsedRealtime 分别记为T2 和t2 T2自然是已经修改完毕的timestamp app启动和用户修改时间 两个事件实际的时间间隔应该为 dt = t2 - t1 而系统时间显示的时间间隔为 dT = T2-T1 因为用户修改过系统时间 这两个时间间隔明显不相等 如果 dT-dt > 0 说明用户把系统时间调快了 反之 dT-dt < 0 说明用户把系统时间调慢了 具体调快调慢多少 就是这个差值的绝对值 abs(dT-dt)
glzlaohuai 2013-05-10
  • 打赏
  • 举报
回复
引用 11 楼 CuGBabyBeaR 的回复:
[quote=引用 10 楼 glzlaohuai 的回复:] [quote=引用 9 楼 CuGBabyBeaR 的回复:] [quote=引用 7 楼 glzlaohuai 的回复:] [quote=引用 6 楼 CuGBabyBeaR 的回复:] 楼主是不是讲 数据在收集的时候 存储数据信息时使用设备时间记录数据的Timestamp 等到合适的时候将数据传输到服务器上 然后服务器以自己的时间矫正Timestamp 但是在数据收集的过程中 客户可能修改设备系统时间? 我想知道的是 精度要求是多高呢? 如果要求不高的话可以这样 在程序启动的时候获取安卓系统启动到现在的时间 然后推算出系统启动的Timestamp并存储 监听日期改变和时间改变的广播 收到广播后再次获取安卓系统启动到现在的时间 推算出在新时间下系统启动的Timestamp存储 并算出时间差 每次记录的时候顺便把时间差也记录下来
因为手机每次reboot之后elapsedTime都会清零,所以在收到时间改变的广播之后用记录的elapsedTime来做计算也是不准确的,不过这个问题可以通过在每次设备开机之后保存当前设备时间跟elapsedTime来解决,但是唯一不完美的地方是还需要加上接收开机启动广播的权限,因为在安装时候用户会疑惑,为什么这东西还需要开机启动?…… 鉴于很少有用户蛋疼的修改自己的时间(时间不准也基本都是在刚买回来用的时候,但也会马上就设置好),所以这个问题就不考虑了,服务器端在统计数据时候先过滤一遍垃圾数据,如果垃圾数据很多,再考虑是否添加“在用户修改时间以后对离线产生的数据做时间同步”的功能。[/quote] 开机启动广播?没必要啊 没必要一开机就记录elapsedTime 既然客户端的时间不准确 不采用 这样就只需要客户端保证获取的数据的时间间隔是正确的就行了 也就是说 在用户更改了系统日期时间后 只需要获取每次日期时间的变化值就好了 例如 在系统开机1分钟整后用户开启了应用 此时系统时间是2013.04.27 21:00:00.000 获得SystemClock.elapsedRealtime() = 60000 (1分钟) 计算出本次开机系统的时间是 2013.04.27 20:59:00.000 (*) 记录这个timestamp 程序运行不知道多久后 收到日期时间改变广播 获取当前 就也就是改变后的系统时间为 2013.04.27 22:00:00.000 获得SystemClock.elapsedRealtime() = 7260000 (2个小时加1分钟) 计算出以改变后的系统时间的开机时间为 2013.04.27 19:59:00.000 和第一个系统时间的timestamp (*)相比较 早了一个小时 说明系统时间调早了一个小时 这样 以后每次用户获取数据的时候 获取的系统时间需要加上一个小时[/quote] elapsedRealtime在每次设备reboot之后都会清零啊,所以它不是一个能作为参考的值,除非你在每次系统boot complete时候记录一下elapsedRealtime以及当前时间戳。如果我设备从来不断电,那可以,但设备室要重启的啊。。。[/quote] 重启有也没关系啊... 主要目的是收到时间日期改变广播后计算出时间的变更值啊... elapsedRealtime只是个辅助工具而已啊[/quote] …… 1、app启动,记录下了timestamp以及elapsedRealtime 2、设备reboot 3、用户修改设备时间 ok,怎么计算
CuGBabyBeaR 2013-05-03
  • 打赏
  • 举报
回复
引用 10 楼 glzlaohuai 的回复:
[quote=引用 9 楼 CuGBabyBeaR 的回复:] [quote=引用 7 楼 glzlaohuai 的回复:] [quote=引用 6 楼 CuGBabyBeaR 的回复:] 楼主是不是讲 数据在收集的时候 存储数据信息时使用设备时间记录数据的Timestamp 等到合适的时候将数据传输到服务器上 然后服务器以自己的时间矫正Timestamp 但是在数据收集的过程中 客户可能修改设备系统时间? 我想知道的是 精度要求是多高呢? 如果要求不高的话可以这样 在程序启动的时候获取安卓系统启动到现在的时间 然后推算出系统启动的Timestamp并存储 监听日期改变和时间改变的广播 收到广播后再次获取安卓系统启动到现在的时间 推算出在新时间下系统启动的Timestamp存储 并算出时间差 每次记录的时候顺便把时间差也记录下来
因为手机每次reboot之后elapsedTime都会清零,所以在收到时间改变的广播之后用记录的elapsedTime来做计算也是不准确的,不过这个问题可以通过在每次设备开机之后保存当前设备时间跟elapsedTime来解决,但是唯一不完美的地方是还需要加上接收开机启动广播的权限,因为在安装时候用户会疑惑,为什么这东西还需要开机启动?…… 鉴于很少有用户蛋疼的修改自己的时间(时间不准也基本都是在刚买回来用的时候,但也会马上就设置好),所以这个问题就不考虑了,服务器端在统计数据时候先过滤一遍垃圾数据,如果垃圾数据很多,再考虑是否添加“在用户修改时间以后对离线产生的数据做时间同步”的功能。[/quote] 开机启动广播?没必要啊 没必要一开机就记录elapsedTime 既然客户端的时间不准确 不采用 这样就只需要客户端保证获取的数据的时间间隔是正确的就行了 也就是说 在用户更改了系统日期时间后 只需要获取每次日期时间的变化值就好了 例如 在系统开机1分钟整后用户开启了应用 此时系统时间是2013.04.27 21:00:00.000 获得SystemClock.elapsedRealtime() = 60000 (1分钟) 计算出本次开机系统的时间是 2013.04.27 20:59:00.000 (*) 记录这个timestamp 程序运行不知道多久后 收到日期时间改变广播 获取当前 就也就是改变后的系统时间为 2013.04.27 22:00:00.000 获得SystemClock.elapsedRealtime() = 7260000 (2个小时加1分钟) 计算出以改变后的系统时间的开机时间为 2013.04.27 19:59:00.000 和第一个系统时间的timestamp (*)相比较 早了一个小时 说明系统时间调早了一个小时 这样 以后每次用户获取数据的时候 获取的系统时间需要加上一个小时[/quote] elapsedRealtime在每次设备reboot之后都会清零啊,所以它不是一个能作为参考的值,除非你在每次系统boot complete时候记录一下elapsedRealtime以及当前时间戳。如果我设备从来不断电,那可以,但设备室要重启的啊。。。[/quote] 重启有也没关系啊... 主要目的是收到时间日期改变广播后计算出时间的变更值啊... elapsedRealtime只是个辅助工具而已啊
glzlaohuai 2013-05-03
  • 打赏
  • 举报
回复
引用 9 楼 CuGBabyBeaR 的回复:
[quote=引用 7 楼 glzlaohuai 的回复:] [quote=引用 6 楼 CuGBabyBeaR 的回复:] 楼主是不是讲 数据在收集的时候 存储数据信息时使用设备时间记录数据的Timestamp 等到合适的时候将数据传输到服务器上 然后服务器以自己的时间矫正Timestamp 但是在数据收集的过程中 客户可能修改设备系统时间? 我想知道的是 精度要求是多高呢? 如果要求不高的话可以这样 在程序启动的时候获取安卓系统启动到现在的时间 然后推算出系统启动的Timestamp并存储 监听日期改变和时间改变的广播 收到广播后再次获取安卓系统启动到现在的时间 推算出在新时间下系统启动的Timestamp存储 并算出时间差 每次记录的时候顺便把时间差也记录下来
因为手机每次reboot之后elapsedTime都会清零,所以在收到时间改变的广播之后用记录的elapsedTime来做计算也是不准确的,不过这个问题可以通过在每次设备开机之后保存当前设备时间跟elapsedTime来解决,但是唯一不完美的地方是还需要加上接收开机启动广播的权限,因为在安装时候用户会疑惑,为什么这东西还需要开机启动?…… 鉴于很少有用户蛋疼的修改自己的时间(时间不准也基本都是在刚买回来用的时候,但也会马上就设置好),所以这个问题就不考虑了,服务器端在统计数据时候先过滤一遍垃圾数据,如果垃圾数据很多,再考虑是否添加“在用户修改时间以后对离线产生的数据做时间同步”的功能。[/quote] 开机启动广播?没必要啊 没必要一开机就记录elapsedTime 既然客户端的时间不准确 不采用 这样就只需要客户端保证获取的数据的时间间隔是正确的就行了 也就是说 在用户更改了系统日期时间后 只需要获取每次日期时间的变化值就好了 例如 在系统开机1分钟整后用户开启了应用 此时系统时间是2013.04.27 21:00:00.000 获得SystemClock.elapsedRealtime() = 60000 (1分钟) 计算出本次开机系统的时间是 2013.04.27 20:59:00.000 (*) 记录这个timestamp 程序运行不知道多久后 收到日期时间改变广播 获取当前 就也就是改变后的系统时间为 2013.04.27 22:00:00.000 获得SystemClock.elapsedRealtime() = 7260000 (2个小时加1分钟) 计算出以改变后的系统时间的开机时间为 2013.04.27 19:59:00.000 和第一个系统时间的timestamp (*)相比较 早了一个小时 说明系统时间调早了一个小时 这样 以后每次用户获取数据的时候 获取的系统时间需要加上一个小时[/quote] elapsedRealtime在每次设备reboot之后都会清零啊,所以它不是一个能作为参考的值,除非你在每次系统boot complete时候记录一下elapsedRealtime以及当前时间戳。如果我设备从来不断电,那可以,但设备室要重启的啊。。。
glzlaohuai 2013-04-27
  • 打赏
  • 举报
回复
引用 4 楼 longer262110 的回复:
[quote=引用 3 楼 glzlaohuai 的回复:] 客户端在保存待上报的统计数据时候不一定是联网的,所以只能用客户端的时间。
不是很明白,你反正最后都需要上报的,上报就需要联网,那为什么不能用服务器时间。[/quote] 对app使用情况做数据统计,开启时间、运行时长等这些数据都是需要记录时间的,app使用过程中不能保证设备的网络连接情况,所以记录中的时间字段都是用的clientTime。
glzlaohuai 2013-04-27
  • 打赏
  • 举报
回复
引用 6 楼 CuGBabyBeaR 的回复:
楼主是不是讲 数据在收集的时候 存储数据信息时使用设备时间记录数据的Timestamp 等到合适的时候将数据传输到服务器上 然后服务器以自己的时间矫正Timestamp 但是在数据收集的过程中 客户可能修改设备系统时间? 我想知道的是 精度要求是多高呢? 如果要求不高的话可以这样 在程序启动的时候获取安卓系统启动到现在的时间 然后推算出系统启动的Timestamp并存储 监听日期改变和时间改变的广播 收到广播后再次获取安卓系统启动到现在的时间 推算出在新时间下系统启动的Timestamp存储 并算出时间差 每次记录的时候顺便把时间差也记录下来
因为手机每次reboot之后elapsedTime都会清零,所以在收到时间改变的广播之后用记录的elapsedTime来做计算也是不准确的,不过这个问题可以通过在每次设备开机之后保存当前设备时间跟elapsedTime来解决,但是唯一不完美的地方是还需要加上接收开机启动广播的权限,因为在安装时候用户会疑惑,为什么这东西还需要开机启动?…… 鉴于很少有用户蛋疼的修改自己的时间(时间不准也基本都是在刚买回来用的时候,但也会马上就设置好),所以这个问题就不考虑了,服务器端在统计数据时候先过滤一遍垃圾数据,如果垃圾数据很多,再考虑是否添加“在用户修改时间以后对离线产生的数据做时间同步”的功能。
CuGBabyBeaR 2013-04-27
  • 打赏
  • 举报
回复
引用 7 楼 glzlaohuai 的回复:
[quote=引用 6 楼 CuGBabyBeaR 的回复:] 楼主是不是讲 数据在收集的时候 存储数据信息时使用设备时间记录数据的Timestamp 等到合适的时候将数据传输到服务器上 然后服务器以自己的时间矫正Timestamp 但是在数据收集的过程中 客户可能修改设备系统时间? 我想知道的是 精度要求是多高呢? 如果要求不高的话可以这样 在程序启动的时候获取安卓系统启动到现在的时间 然后推算出系统启动的Timestamp并存储 监听日期改变和时间改变的广播 收到广播后再次获取安卓系统启动到现在的时间 推算出在新时间下系统启动的Timestamp存储 并算出时间差 每次记录的时候顺便把时间差也记录下来
因为手机每次reboot之后elapsedTime都会清零,所以在收到时间改变的广播之后用记录的elapsedTime来做计算也是不准确的,不过这个问题可以通过在每次设备开机之后保存当前设备时间跟elapsedTime来解决,但是唯一不完美的地方是还需要加上接收开机启动广播的权限,因为在安装时候用户会疑惑,为什么这东西还需要开机启动?…… 鉴于很少有用户蛋疼的修改自己的时间(时间不准也基本都是在刚买回来用的时候,但也会马上就设置好),所以这个问题就不考虑了,服务器端在统计数据时候先过滤一遍垃圾数据,如果垃圾数据很多,再考虑是否添加“在用户修改时间以后对离线产生的数据做时间同步”的功能。[/quote] 开机启动广播?没必要啊 没必要一开机就记录elapsedTime 既然客户端的时间不准确 不采用 这样就只需要客户端保证获取的数据的时间间隔是正确的就行了 也就是说 在用户更改了系统日期时间后 只需要获取每次日期时间的变化值就好了 例如 在系统开机1分钟整后用户开启了应用 此时系统时间是2013.04.27 21:00:00.000 获得SystemClock.elapsedRealtime() = 60000 (1分钟) 计算出本次开机系统的时间是 2013.04.27 20:59:00.000 (*) 记录这个timestamp 程序运行不知道多久后 收到日期时间改变广播 获取当前 就也就是改变后的系统时间为 2013.04.27 22:00:00.000 获得SystemClock.elapsedRealtime() = 7260000 (2个小时加1分钟) 计算出以改变后的系统时间的开机时间为 2013.04.27 19:59:00.000 和第一个系统时间的timestamp (*)相比较 早了一个小时 说明系统时间调早了一个小时 这样 以后每次用户获取数据的时候 获取的系统时间需要加上一个小时
CuGBabyBeaR 2013-04-17
  • 打赏
  • 举报
回复
楼主是不是讲 数据在收集的时候 存储数据信息时使用设备时间记录数据的Timestamp 等到合适的时候将数据传输到服务器上 然后服务器以自己的时间矫正Timestamp 但是在数据收集的过程中 客户可能修改设备系统时间? 我想知道的是 精度要求是多高呢? 如果要求不高的话可以这样 在程序启动的时候获取安卓系统启动到现在的时间 然后推算出系统启动的Timestamp并存储 监听日期改变和时间改变的广播 收到广播后再次获取安卓系统启动到现在的时间 推算出在新时间下系统启动的Timestamp存储 并算出时间差 每次记录的时候顺便把时间差也记录下来
longer262110 2013-04-17
  • 打赏
  • 举报
回复
引用 4 楼 longer262110 的回复:
引用 3 楼 glzlaohuai 的回复: 客户端在保存待上报的统计数据时候不一定是联网的,所以只能用客户端的时间。 不是很明白,你反正最后都需要上报的,上报就需要联网,那为什么不能用服务器时间。
你是必须要那个差值是吗?
longer262110 2013-04-17
  • 打赏
  • 举报
回复
引用 3 楼 glzlaohuai 的回复:
客户端在保存待上报的统计数据时候不一定是联网的,所以只能用客户端的时间。
不是很明白,你反正最后都需要上报的,上报就需要联网,那为什么不能用服务器时间。
glzlaohuai 2013-04-17
  • 打赏
  • 举报
回复
客户端在保存待上报的统计数据时候不一定是联网的,所以只能用客户端的时间。
aotian16 2013-04-17
  • 打赏
  • 举报
回复
不用客户端的时间不行吗, 一直用服务端的时间
glzlaohuai 2013-04-17
  • 打赏
  • 举报
回复
求关注啊,如果在每次系统广播时间改变的时候能同时携带改变的时间就好了,哎。

80,471

社区成员

发帖
与我相关
我的任务
社区描述
移动平台 Android
androidandroid-studioandroidx 技术论坛(原bbs)
社区管理员
  • Android
  • yechaoa
  • 失落夏天
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧