如何处理服务器中数据的时区差异,尤其是IOT平台

时间:2017-06-06 00:39:12

标签: java datetime architecture server timezone

我正在寻找解决方案,如何处理具有特定时间相关数据的数据。

项目架构: 后端是用Java构建的RESTful服务。

前端是: 1. Angular JS(仅限网络) 2.原生移动应用程序(Android,iPhone)。

  

例如。一台设备在英国(即UTC + 1:00)时区另一台设备   在HKT(香港,即UTC + 8:00)时区。

     

我的服务器位于德国(即UTC +2:30)时区。

我应该在服务器上保留什么?

如何显示每个设备(网络浏览器以及移动设备)的当前时间,如果我正在提供可以从任何地方访问的网页,我应该保留哪个时区值?

目前的解决方案: 目前我保持数据到达服务器时计算UTC纪元时间并存储它,通过REST发送时间,然后在客户端(网络浏览器或Android设备)我将其转换为本地时区。

这种做法是否正确?

1 个答案:

答案 0 :(得分:2)

是的,你的方法似乎很正确。

对于您的实施:如果您使用 Java 8 ,请考虑使用new java.time API。它更容易,less bugged and less error-prone than the old APIs

如果您使用的是 Java< = 7 ,则可以使用ThreeTen Backport,这是Java 8新日期/时间类的绝佳后端。对于 Android ,有ThreeTenABP(更多关于如何使用它here)。

以下代码适用于两者。唯一的区别是包名称(在Java 8中为java.time而在ThreeTen Backport中为org.threeten.bp),但类和方法名称是相同的。

要获得UTC时间,您可以使用Instant课程。这是最好的选择,因为它始终是UTC,可以很容易地转换到另一个时区:

// get current UTC time - Instant is always in UTC
Instant instant = Instant.now();

// you can use the string representation
System.out.println(instant.toString());// 2017-06-06T11:57:21.665Z
// or the timestamp (epoch millis - milliseconds from 1970-01-01T00:00:00Z)
System.out.println(instant.toEpochMilli());// 1496750241665

// convert to another timezone (always use valid IDs)
ZonedDateTime z = instant.atZone(ZoneId.of("America/Sao_Paulo"));
System.out.println(z);// 2017-06-06T08:57:21.665-03:00[America/Sao_Paulo]

// in another timezone
z = instant.atZone(ZoneId.of("Europe/Berlin"));
System.out.println(z);// 2017-06-06T13:57:21.665+02:00[Europe/Berlin]

// convert back to UTC Instant
System.out.println(z.toInstant()); // 2017-06-06T11:57:21.665Z

API使用IANA timezones names(始终采用Continent/City格式,如America/Sao_PauloEurope/Berlin。避免使用3个字母的缩写(例如CSTPST),因为它们是ambiguous and not standard。您可以使用ZoneId.getAvailableZoneIds()获取所有时区名称的完整列表。

您还可以使用ZoneId.systemDefault()获取系统的默认时区。在这种情况下,如果代码在服务器上运行,它将使用服务器的机器时区。如果它在设备中运行,它将使用设备中配置的任何内容。