我有Java 8 Spring网络应用程序,它将支持多个区域。我需要为客户位置制作日历活动。因此,假设我的网站和Postgres服务器托管在MST时区(但我想如果我们去云端,它可能就在任何地方)。但客户是在美国东部时间。所以,按照我读到的一些最佳实践,我想我会以UTC格式存储所有日期时间。数据库中的所有日期时间字段都声明为TIMESTAMP。
以下是我如何使用LocalDateTime并转换为UTC:
ZonedDateTime startZonedDT = ZonedDateTime.ofLocal(dto.getStartDateTime(), ZoneOffset.UTC, null);
//appointment startDateTime is a LocalDateTime
appointment.setStartDateTime( startZonedDT.toLocalDateTime() );
现在,例如,当搜索日期时,我必须将请求的日期时间转换为UTC,获取结果并转换为用户时区(存储在数据库中):
ZoneId userTimeZone = ZoneId.of(timeZone.getID());
ZonedDateTime startZonedDT = ZonedDateTime.ofLocal(appointment.getStartDateTime(), userTimeZone, null);
dto.setStartDateTime( startZonedDT.toLocalDateTime() );
现在,我不确定这是正确的做法。我也想知道,因为我是从LocalDateTime转到ZonedDateTime,反之亦然,我可能会失去任何时区信息。
这是我所看到的,对我来说似乎不正确。当我从UI收到LocalDateTime时,我得到了这个:
2016-04-04T08:00
ZonedDateTime =
dateTime=2016-04-04T08:00
offset="Z"
zone="Z"
然后当我将转换后的值分配给我的约会LocalDateTime时,我存储:
2016-04-04T08:00
我觉得因为我存储在LocalDateTime中,我失去了转换为ZonedDateTime的时区。
我是否应该让我的实体(约会)使用ZonedDateTime而不是LocalDateTime,以便Postgres不会丢失这些信息?
---------------- 编辑 ----------------
在Basils出色的答案之后,我意识到我有一个不关心用户时区的奢侈 - 所有约会都是针对特定位置的,因此我可以将所有日期时间存储为UTC,然后在检索时将它们转换为位置时区。我做了以下跟进question
答案 0 :(得分:1)
TLDR:
要从LocalDateTime转换为ZonedDateTime,请执行以下代码。您可以使用.atZone( zoneId )
,在TZ database name
on Wikipedia.
LocalDateTime localDateTime = LocalDateTime.parse( "2016-04-04T08:00" );
ZoneId zoneId = ZoneId.of( "UTC" ); // Or "Asia/Kolkata" etc.
ZonedDateTime zdt = localDateTime.atZone( zoneId );