我正在开发一个Scala项目,需要将OffsetDateTime
类型映射到SQL的Timestamp
类型。在数据库中,我希望使用UTC时间。
从OffsetDateTime
转换为Timestamp
很简单(来自这个问题的提示),并且可以按预期工作:
import java.time._
import java.sql.Timestamp
val ofsdatetime = OffsetDateTime.now()
// ofsdatetime: java.time.OffsetDateTime = 2017-04-04T21:46:33.567+02:00
val tstamp = Timestamp.valueOf(ofsdatetime.atZoneSameInstant(ZoneOffset.UTC).toLocalDateTime())
// tstamp: java.sql.Timestamp = 2017-04-04 19:46:33.567
正如你所看到的,时区被移除并且时间戳是在时间上向前推了两个小时(UTC),非常好!
将 Timestamp
转换回 OffsetDateTime
意料之外地无法正常工作:
OffsetDateTime.ofInstant(Instant.ofEpochMilli(tstamp.getTime), ZoneId.systemDefault())
// java.time.OffsetDateTime = 2017-04-04T19:46:33.567+02:00
新创建的OffsetDateTime
已添加时区信息,但时间不正确(仍然是UTC),我需要它适应实际时区。
为什么?我做错了什么?
Timestamp.toInstant()
吗?你上面的代码调用了:Instant.ofEpochMilli(tstamp.getTime)
。据我所知,我们会失去毫秒以下的精度。 - kevinarpeOffsetDateTime.ofInstant
与任何时区相结合,对一个瞬间进行操作,这将是“正确的时间点”,即底层纪元不会改变。 - taylorcressyOffsetDateTime.ofInstant(Instant.ofEpochMilli(tstamp.getTime), ZoneId.of("UTC"))
和OffsetDateTime.ofInstant(Instant.ofEpochMilli(tstamp.getTime), ZoneId.of("America/Los_Angeles"))
都是正确的。它们都是从数据库中检索日期的有效方法。这取决于应用程序所需的基于时区的表示方式。您的解释对于java.util.Date(epoch)的真实含义存在误解。 - taylorcressy