我正在寻找解决方案,如何处理具有特定时间相关数据的数据。
项目架构: 后端是用Java构建的RESTful服务。
前端是: 1. Angular JS(仅限网络) 2.原生移动应用程序(Android,iPhone)。
例如。一台设备在英国(即UTC + 1:00)时区另一台设备 在HKT(香港,即UTC + 8:00)时区。
我的服务器位于德国(即UTC +2:30)时区。
我应该在服务器上保留什么?
如何显示每个设备(网络浏览器以及移动设备)的当前时间,如果我正在提供可以从任何地方访问的网页,我应该保留哪个时区值?
目前的解决方案: 目前我保持数据到达服务器时计算UTC纪元时间并存储它,通过REST发送时间,然后在客户端(网络浏览器或Android设备)我将其转换为本地时区。
这种做法是否正确?
答案 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_Paulo
或Europe/Berlin
。避免使用3个字母的缩写(例如CST
或PST
),因为它们是ambiguous and not standard。您可以使用ZoneId.getAvailableZoneIds()
获取所有时区名称的完整列表。
您还可以使用ZoneId.systemDefault()
获取系统的默认时区。在这种情况下,如果代码在服务器上运行,它将使用服务器的机器时区。如果它在设备中运行,它将使用设备中配置的任何内容。