在AChat项目的开发过程中,项目要求无论终端是什么时区设置、地处何方,终端的时间是否正确,post到服务器的数据包里面的时间字段均要求跟服务器同步,也就是说,用户买来一部新手机、新平板,不做任何日期时间、时区方面的设置,装了App就用,也能让时间数据正确。
我是这样设计的,在app的setting中有3个变量org_tablet_tm,org_server_tm和server_timezone,App启动的时候,即联线服务器取回当时的时间和服务器所在时区分别保存在org_server_tm和server_timezone,同一刻,取终端的时间保存在org_tablet_tm。
定义now()函数,此函数取当前设备时间再加上org_server_tm-org_tablet_tm的差值。
好了,这时候尽管设备终端的时间乱七八糟,只要时区跟服务器时区一致,用now()函数即可获得服务器上此时此刻的时间。
但是,问题来了,每个用户的终端设备时区不一定跟服务器上的一致,有可能他们根本没调时间、或没勾上自动同步时间,这时候需要我们用代码实现在终端不同时区也能跟服务器上的时间同步。
先看看这个DateTimeConvertToServer这个函数,先从tm中减去当前时区跟格林威治之间的时间差,再加上服务器所在时区跟格林威治时间差,即可算出到服务器时间:
再看getDiffTimeZoneRawOffsetStd函数,用于计算指定时区跟格林威治时区的时间差(毫秒):
我在参数里面配置一个选项”是否转换成终端时间“,若转换,则什么都不做,因为Android系统能根据当前设置的时区自动转换时间,若不转换,则显示服务器端时间,则需要用DateTimeConvertToServer函数转换一下。
补充一下截图,当前平板时间乱套,时区是巴库asia/baku,服务器是东8区,下面是平板截图:
服务器上保存的数据:
==================================
完结前吐槽一下,网络上流传一段时区差的计算函数,它们用TimeZone的getRawOffset,当时我也抄来用,各种时区试一遍,开始是各种适合,但测试到Asia/Baku时顿时石化了,同样是东5区的卡拉奇、乌拉尔都没问题,自巴库起开始一路往西的时区都相差一小时!!!用getRawOffset获得巴库离格林威治差4小时,但应该是5小时!!由于时间问题没仔细分析什么原因,有空再看并。
==================================
然而更狗血的事件发生了,在公司做的一批平板上运行APP,发现 android 4.2的老平板, 默认的American/New York按上述方法转为服务器的东8区时间问题要快1小时, 在android 4.4.2上则没有这个问题! 后来调试发现American/New York时区在这平板上相差GMT -5 ! 而在我的华为手机上为GMT -4!
不明白为什么会这样! 但换另一种做法,就是设置平板默认与服务器上的相同无需手动计算差值,则所有问题得到解决:
网友评论