首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何处理服务器与本地android应用程序之间的时区差异?

如何处理服务器与本地android应用程序之间的时区差异?
EN

Stack Overflow用户
提问于 2013-08-11 07:18:13
回答 5查看 8.1K关注 0票数 12

假设我的服务器位于美国,我住在俄罗斯。我们知道他们有不同的时区。

我的应用程序从服务器获取文本(String)。而本文的数据在数据库中有Date列来保存记录日期。

当我得到数据时,我也得到了date知识。这样我就可以按时间分组了。头一个在顶部,最后一个在底部。不管什么..。

我编写了一个函数来显示日期值,例如"13小时“,"9分钟”。服务器在服务器(美国)时区向我发送日期。

当我用俄罗斯时区(因为它是应用程序上的当前时区)计算应用时间时,它计算错误。所以这不是任何人想要的东西。

我应该怎么做才能达到正确的计算?

注释:这个应用程序将被不同国家的公民使用。所以我不能把计算变成静态的。

EN

回答 5

Stack Overflow用户

发布于 2013-08-11 19:47:41

没有真正的“俄罗斯时区”或“美国时区”这样的东西。这两个国家都有若干不同的时区。请参阅维基百科关于俄罗斯时间在美国的时间的文章。

您应该始终编写服务器代码,使其不依赖于运行服务器的时区。通常,这是通过将所有时间存储为UTC来完成的。由于客户机是Android设备,所以只需在客户机上的本地时间进行转换,只将UTC发送到/从服务器发送。

如果您是用Java工作的,那么您可能应该使用Joda时间进行转换。它比Calendar类干净得多,使用起来也更容易。

更新

正如Basil在评论中指出的,Joda-Time项目现在处于维护模式.该团队建议迁移到由java.time定义的JSR 310类。关于早期的Android,请参阅三次-支持ThreeTenABP项目。见如何使用…

票数 6
EN

Stack Overflow用户

发布于 2013-08-11 07:22:55

Calendar类可以在时区之间转换时间,只要您知道服务器和客户端使用哪个时区。为了避免将来在移动服务器时出现问题,最好定义数据库中的时间。我更愿意使用UTC作为它的标准,但是您可以使用任何您想要使用的时区,只要它已经定义好了,并且在您的文档中也是如此,这样以后您就会知道了。

下面是一个问题,展示了如何做到这一点:将日期和时间转换为java中的其他时区

票数 2
EN

Stack Overflow用户

发布于 2017-12-15 16:03:11

tl;dr

时区与经过的小时-分钟-秒无关。

代码语言:javascript
运行
复制
Duration.between(
    Instant.parse( "2017-12-14T01:34:56.123456789Z" ) ;
    Instant.now() 
)

java.time

现代方法使用业界领先的java.time类。它们取代了麻烦的旧式日期时间类,如DateCalendar

服务器通常应该设置为UTC的时区。你不应该依赖任何这样的环境。相反,您的代码应该指定所需/预期的时区。

您的业务逻辑、数据存储和数据交换都应该在UTC中作为一般规则。当序列化为文本时,只使用标准的ISO 8601格式。

在必要时应用其他时区,如用户在用户界面中所期望的那样。因此,通常您应该将UTC以外的时区视为本地化问题。

Instant

Instant类以纳秒的分辨率表示时间轴上的时间点。获取当前时刻不受时区设置的影响。

代码语言:javascript
运行
复制
Instant instant = Instant.now() ;

通过调用toString以标准格式序列化为文本。

代码语言:javascript
运行
复制
String output = instant.toString() ;

您可以与数据库交换Instant

代码语言:javascript
运行
复制
myPreparedStatement.setObject( … , instant ) ;

…和…

代码语言:javascript
运行
复制
Instant instant = myPreparedStatement.getObject( … , Instant.class ) ;

ZonedDateTime

应用ZoneId来获得ZonedDateTime

代码语言:javascript
运行
复制
ZoneId z = ZoneId.of( "America/Montreal" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;

若要以非标准格式生成字符串,请使用DateTimeFormatter类。搜索堆栈溢出的许多例子和讨论。

Duration

要获得经过的小时、分钟、秒数,请使用Duration类。注意,您不需要经过时间的时区;UTC (Instant)给出了相同的结果。

代码语言:javascript
运行
复制
Duration d = Duration.between( then , Instant.now() ) ;

关于早期的Android,请参阅http://www.threeten.org/threetenbp/https://github.com/JakeWharton/ThreeTenABP项目。见https://stackoverflow.com/questions/38922754/how-to-use-threetenabp-in-android-project

关于java.time

java.time框架内置到Java8和更高版本中。这些类取代了麻烦的旧遗赠日期时间类,如java.util.DateCalendarSimpleDateFormat

尤达-时间项目现在在维护模式中,建议迁移到java.time类。

要了解更多信息,请参见Oracle教程。并搜索堆栈溢出以获得许多示例和解释。规范是JSR 310

在哪里获得java.time类?

  • Java 8Java 9,以及后来的
    • 内置的。
    • 带有捆绑实现的标准Java的一部分。
    • Java 9添加了一些次要的特性和修复。

  • Java 6Java 7
    • java.time的大部分功能都是在http://www.threeten.org/threetenbp/中移植到Java6&7中的。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18169669

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档