如何保证两端时间一致性

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何保证两端时间一致性相关的知识,希望对你有一定的参考价值。

android与服务器通讯:如何保证两端时间一致性
在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的差值。

/**
* 永远以server为准
* @return
*/
public static Date now()
Date w_ret=new Date();
w_ret.setTime(w_ret.getTime()+(org_server_tm-org_tablet_tm));
return w_ret;


好了,这时候尽管设备终端的时间乱七八糟,只要时区跟服务器时区一致,用now()函数即可获得服务器上此时此刻的时间。

但是,问题来了,每个用户的终端设备时区不一定跟服务器上的一致,有可能他们根本没调时间、或没勾上自动同步时间,这时候需要我们用代码实现在终端不同时区也能跟服务器上的时间同步。
先看看这个DateTimeConvertToServer这个函数,先从tm中减去当前时区跟格林威治之间的时间差,再加上服务器所在时区跟格林威治时间差,即可算出到服务器时间:

/***
* 把当地的时间转为服务器当时的时间,一般递交数据前先把Date一类数据转换
* @param tm
* @return
*/
public static Date DateTimeConvertToServer(Date tm)
if (tm==null)return null;
tm=new Date(tm.getTime()-getDiffTimeZoneRawOffsetStd(TimeZone.getDefault().getID())); //转成格林威治时间
Date d=new Date(tm.getTime()+getDiffTimeZoneRawOffsetStd(server_timezone));
return d;


再看getDiffTimeZoneRawOffsetStd函数,用于计算指定时区跟格林威治时区的时间差(毫秒):

/***
* 计算出指定时区跟格林威治时间差
* @param timeZoneId
* @return
*/
public static int getDiffTimeZoneRawOffsetStd(String timeZoneId)
//return TimeZone.getTimeZone(timeZoneId).getRawOffset();
TimeZone tz = TimeZone.getTimeZone(timeZoneId);
return tz.getOffset(GregorianCalendar.getInstance(tz).getTimeInMillis());


我在参数里面配置一个选项”是否转换成终端时间“,若转换,则什么都不做,因为Android系统能根据当前设置的时区自动转换时间,若不转换,则显示服务器端时间,则需要用DateTimeConvertToServer函数转换一下。

补充一下截图,当前平板时间乱套,时区是巴库asia/baku,服务器是东8区,下面是平板截图:

服务器上保存的数据:

==================================
完结前吐槽一下,网络上流传一段时区差的计算函数,它们用TimeZone的getRawOffset,当时我也抄来用,各种时区试一遍,开始是各种适合,但测试到Asia/Baku时顿时石化了,同样是东5区的卡拉奇、乌拉尔都没问题,自巴库起开始一路往西的时区都相差一小时!!!用getRawOffset获得巴库离格林威治差4小时,但应该是5小时!!由于时间问题没仔细分析什么原因,有空再看并。
参考技术A 保证两端时间一致性是指在Android与服务器通讯中保证两端时间一致性,方法如下: 1、在app的setting中有3个变量org_tablet_tm,org_server_tm和server_timezone,App启动的时候,即联线服务器取回当时的时间和服务器所在时区分别保存在org_serve...

如何保证类专业化是一致的

【中文标题】如何保证类专业化是一致的【英文标题】:How to guarantee that class specializations are consistent 【发布时间】:2017-07-03 22:32:40 【问题描述】:

我有两个抽象类,代表一个组合:

国家(由组成)

我有这两个类的具体化,例如:

国家法国意大利 人物FrenchGuyItalianGuy

Country 抽象类作为人员列表作为属性:peopleList:People

我如何保证 France 类 peopleList 属性将仅填充 FrenchGuyItalyItalianGuy,并使其保持一致?

我设计它的方式是反模式吗?

提前感谢您的回答

【问题讨论】:

您在示例中将“是一种”与“是一种实例”混为一谈。这是一个巨大的反模式! 今天晚些时候我可能有时间解释如何正确执行此操作。使用泛化集是一个红鲱鱼。 @JimL.: 你在你的例子中把“is a kind of”和“is an instance of”混为一谈了。:确实我的例子不是很好选择。就我而言,法国和意大利需要是专业化而不是实例。例如,France 会有一个 getCheese() 方法,而 Italy 会有一个 getPizza() 一个类大致对应一个实例集。在名为“法国”的集合中有哪些实例?如果你用一个可行的图表来更新这个问题,我可以告诉你如何说左边的东西在右边只有一种更具体的东西。我不能用一个无效的例子来做到这一点。 好的,让我们使用一个经典的保险示例。假设我在上面的示例中称为“国家/地区”,即保险。 'France' 和 'Italy' 是 InsuranceType1InsuranceType2 假设“People”是 Position。 'FrenchGuy' 和 'ItalianGuy' 是 CivilServantCompanyEmployee。问题是,如何将 InsuranceType1 连接到 CivilServant,将 InsuranceType2 连接到 CompanyEmployee 【参考方案1】:

我将用一个不会混淆“是一种”和“是一种实例”的例子来回答这个问题。 (有关更多详细信息,请参阅我关于原始问题的 cmets。)

确实,您可以保证特定专业仅与某些其他专业相关联。您可以使用 UML 关联特化和属性重定义来做到这一点。

我将带您了解这个 UML 图告诉我们的内容:

Insurance PolicyInsurable Thing 之间有一个未命名的关联,它有两个属性:insuresinsured by。它告诉我们,一般情况下,每个Insurance Policy一个或多个Insurable Things 提供保险,每个Insurable Thing 可以由任意数量的Insurance Policies 提供保险。 ¹ Insurance Policy 有两个不相交的² 特化:Health Insurance PolicyCar Insurance PolicyInsurable Thing 有两个不相交的特化:CarPerson。 顶部的未命名关联有两个具有更具体属性约束的专业关联: Car Insurance PolicyCar 之间的关联具有重新定义(即收紧)其允许类型的属性。 Health Insurance PolicyPerson 之间的关联具有重新定义(即收紧)其允许类型的属性。

专业协会和重新定义正在这里完成所有工作。如果您愿意,您可以进一步收紧多重性,甚至更改属性名称³。


¹ 请注意,UML 最近采用了一种“点表示法”,这使得关联末端没有点的情况变得不明确。前点表示法,可导航属性由关联另一端的类拥有。后点表示法,可导航属性归关联所有——除了少数工具支持它,而那些支持它的工具,例如 MagicDraw,在项目选项中默认关闭点 off !我个人觉得点符号很可怕,所以这个例子没有使用它,这意味着属性归其关联另一端的类所有。

² 不相交意味着没有任何东西可以是两种专业化的实例,许多实现语言不允许,但现实世界和 UML允许。不完整意味着可能还有其他类型的保险单我们没有调用,可以直接实例化通用Insurance Policy

³ 如果您更改属性名称,这意味着,在其所有者的上下文中,该名称使一般所有者中的名称黯然失色。如果您“向上转换”专业化,则相同的属性将具有其原始名称,因为它位于广义所有者的上下文中。

【讨论】:

好的,谢谢 Jim L. 的详细回答。在实现方面,我想这不像简单的继承那样简单,或者像组合或聚合这样的东西。在 DB 级别(通过 ORM 抽象)和程序级别(不考虑 DB)是否有一种众所周知的模式来获得这种结构? 对于 ORM,请参阅 Class Table Inheritance 或 Concrete Table Inheritance。每个表都有自己特定的外键。使用 OO 语言中的方法来实现这个 UML 图非常简单,所以我不确定还有什么要说的。【参考方案2】:

基本上你可以通过使用Generalization Sets 来做到这一点。这将确保来自ItalyItalian Guy 的概括(您有一个仅限男性的国家?)是相关的,因此您将只有“正确”的人口。

【讨论】:

我不完全理解您提供的关于泛化集和 subsequent example 的链接中描述的内容。例如之间的联系如何在我的例子中 ItalyItalian guy 是物化了吗?这就是他们所说的电源类型吗? 您可以使用特定国家/地区键入每个概括(:France:Italy)。您可能不需要任何约束。或者,您可以将组合从抽象移到特定类。

以上是关于如何保证两端时间一致性的主要内容,如果未能解决你的问题,请参考以下文章

Cassandra如何保证数据最终一致性

如何保证solr跟数据库的数据一致性

如何保证session的一致性session.save

如何保证solr跟数据库的数据一致性

大厂面试01期高并发场景下,如何保证缓存与数据库一致性?

大厂面试01期高并发场景下,如何保证缓存与数据库一致性?