万事须己运,他得非我贤。这篇文章主要讲述如何处理服务器和本机android应用程序之间的时区差异?相关的知识,希望能为你提供帮助。
假设我的服务器位于美国,我住在俄罗斯。我们知道他们有不同的时区。
【如何处理服务器和本机android应用程序之间的时区差异()】我的应用程序从服务器获取文本(String
)。而这个文本数据在数据库中有Date
列以保存记录日期。
当我获得数据时,我也获得了date
的知识。所以我可以按时间分组。顶部的第一个和底部的最后一个。随你...
我写了一个函数来显示日期值更人性化,如“13小时”,“9分钟”。服务器在服务器(美国)时区发送日期。
当我用俄罗斯时区计算申请时间时(因为它是申请时的当前时区),它计算错误。所以,这不是任何人想要的东西。
我该怎么做才能实现正确的计算?
注释:此应用程序将由不同国家的公民使用。所以我无法使计算静态。
答案没有“俄罗斯时区”或“美国时区”这样的东西。这两个国家都有几个不同的时区。请参阅有关Time in Russia和Time in the USA的维基百科文章。
您应该始终编写服务器代码,使其不依赖于服务器运行的时区。通常这是通过将所有时间存储为UTC来完成的。由于客户端是android设备,只需在客户端上转换为本地时间,从服务器发送UTC或从服务器发送UTC。
如果您使用的是java,那么您应该使用Joda Time进行转换。它比Calendar
类更清洁,更容易使用。
更新
正如Basil在评论中指出的那样,Joda-Time项目现在处于维护模式。该团队建议迁移到java.time
定义的JSR 310类。对于早期的Android,请参阅ThreeTen-Backport和ThreeTenABP项目。见How to use…。
另一答案Calendar类可以在时区之间转换时间,只要您知道服务器和客户端使用的时区即可。如果您移动服务器以避免将来出现问题,最好定义数据库中的时间。我更喜欢使用UTC作为其标准,但您可以使用您希望的任何时区,只要它已定义并在您的文档中,以便您将来知道。
这是一个显示如何做的问题:Date and time conversion to some other Timezone in java
另一答案
tl;
dr时区与经过的小时 - 分钟 - 秒无关。
Duration.between(
Instant.parse( "2017-12-14T01:34:56.123456789Z" ) ;
Instant.now()
)
java.time现代方法使用业界领先的java.time类。这些取代了麻烦的旧遗留日期时间类,如
Date
和Calendar
。通常应将服务器设置为UTC的时区。你永远不应该依赖任何这样的设置。相反,您的代码应指定所需/预期的时区。
作为一般规则,您的业务逻辑,数据存储和数据交换都应该是UTC。序列化为文本时,仅使用标准ISO 8601格式。
必要时应用其他时区,如用户在用户界面中所期望的那样。因此,通常您应该将UTC以外的时区视为本地化问题。
Instant
Instant
类表示一个时刻,UTC时间轴上的一个点,分辨率为纳秒。获取当前时刻不受时区设置的影响。Instant instant = Instant.now() ;
通过调用
toString
以标准格式序列化为文本。String output = instant.toString() ;
您可以将
Instant
与您的数据库进行交换。myPreparedStatement.setObject( … , instant ) ;
…和…
Instant instant = myPreparedStatement.getObject( … , Instant.class ) ;
ZonedDateTime
使用ZoneId
来获得ZonedDateTime
。ZoneId z = ZoneId.of( "America/Montreal" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;
要以非标准格式生成字符串,请使用
DateTimeFormatter
类。搜索Stack Overflow以获取许多示例和讨论。Duration
要获得经过的小时数,分钟数,秒数,请使用Duration
类。请注意,您不需要经过时间的时区;
UTC(Instant
)给出了相同的结果。Duration d = Duration.between( then , Instant.now() ) ;
对于早期的Android,请参阅ThreeTen-Backport和ThreeTenABP项目。见How to use…。
About java.timejava.time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,如
java.util.Date
,Calendar
和SimpleDateFormat
。现在在Joda-Time的maintenance mode项目建议迁移到java.time班。
要了解更多信息,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。规格是JSR 310。
从哪里获取java.time类?
- Java SE 8,Java SE 9,以及之后 内置。 带有捆绑实现的标准Java API的一部分。 Java 9增加了一些小功能和修复。
- Java SE 6和Java SE 7 大部分java.time功能都在ThreeTen-Backport中反向移植到Java 6和7。
- Android ThreeTenABP项目特别适用于Android的ThreeTen-Backport(如上所述)。 见How to use ThreeTenABP…。
另一答案如果您在Java 8之前使用Java,那么您应该使用Joda Time进行转换。看看这个问题:Date and time conversion to some other Timezone in java
如果您正在使用Java 8及更高版本(或者如果您计划在公司中启动升级过程),Java 8将包含一个正确的日期/时间库,并且Joda的创建者建议切换到使用它。看看这个问题:Joda Time - Convert UTC DateTime to Date - Using a Version 1.2.1.1 of Joda
推荐阅读
- 在rails中创建像app这样的facebook页面
- Android - 如何为随机数设置动画()
- 如何将容器blob下载到Azure App Service wwwroot()
- 从VSTS设置App Identity的文件夹权限()
- Azure WebApp上VS持续交付的程序集错误
- Android Worklight应用程序中的启动画面后,黑屏会长时间出现
- android-数据在viewPage中丢失
- 从Android Studio到桌面软件的最佳进展()
- 如何使用Gradle为Android项目生成Eclipse和Intellij项目文件