LocalDateTime到ZonedDateTime

时间:2016-04-05 04:46:58

标签: java spring-data-jpa postgresql-9.3 java-time

我有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

1 个答案:

答案 0 :(得分:1)

TLDR:

要从LocalDateTime转换为ZonedDateTime,请执行以下代码。您可以使用.atZone( zoneId ),在TZ database name on Wikipedia.

列中找到zoneID的完整列表。
LocalDateTime localDateTime = LocalDateTime.parse( "2016-04-04T08:00" );
ZoneId zoneId = ZoneId.of( "UTC" ); // Or "Asia/Kolkata" etc.
ZonedDateTime zdt = localDateTime.atZone( zoneId );