这是从日期获取UTC的java.sql.Timestamp的正确方法吗?

fge*_*fge 6 java java-8 java-time

我开发了一个SonarQube插件,为了满足我的一个需求,我需要将项目的分析日期存储为SQL TIMESTAMP(请注意: a TIMESTAMP,而不是 a TIMESTAMP WITH TIMEZONE).

以下是我目前的工作方式:

// In the SonarQube Sensor
// .getAnalysisDate() returns a java.util.Date
final Instant instant = module.getAnalysisDate().toInstant();

// Timestamp at UTC from the Instant
final LocalDateTime dt = LocalDateTime.frominstant(instant, ZoneOffset.UTC);
final Timestampt ts = Timestamp.valueOf(dt);
Run Code Online (Sandbox Code Playgroud)

抓住Instant的概念我有点麻烦,还有ZonedDateTime等......

无论如何,这似乎做我想要的,但这是正确的方法吗?

ass*_*ias 5

要将UTC存储TIMESTAMP在数据库中,您需要创建一个Java Timestamp,该Java 代表报告的日期(例如UTC 11月8日晚上7点),但是要在本地时区进行转换(例如CET 11月8日7pm)。因此,您的方法是正确的:LocalDateTime在UTC(11月8日晚上7点)中获取分析日期,然后在该时区中创建时间戳LocalDateTime

我认为没有更短/更好的方法可以做到这一点。如果使用sql TIMESTAMP WITH TIME ZONE字段,则无需进行任何操作即可Date.from(Instant)产生正确的结果。


以您发布问题的时间为例(2015年11月8日(星期日)世界标准时间),并假设您所在的时区为CET(欧洲中部时间= UTC + 1),以澄清相关概念:

  • Java Timestamp将是自该纪元以来的毫秒数,即Java 代表您发布问题的时间线上的唯一时刻,并且没有任何时区信息
  • 将其存储TimestampTIMESTAMP(即没有时区)字段时,jdbc驱动程序将计算Timestamp默认时区中与您相对应的日期/时间(除非Calendar明确提供了a)-因此您的数据库将在11月8日星期日晚上8点显示
  • a java.time.Instant类似于Java Timestamp:它表示唯一的时间点,没有时区信息
  • a LocalDateTime就像一个sql TIMESTAMP,它表示例如11月8日,星期日,晚上8点,但是您不知道没有其他时区信息的时间点
  • a ZonedDateTime本质上是一个LocalDateTime+时区。例如,11月8日(星期日)晚上8点[欧洲/巴黎]-通常标识一个唯一的瞬间,但不一定是唯一的(想想夏令时的时钟向后更改,同一小时重复两次)。
  • an OffsetDateTime本质上是LocalDateTime相对于UTC 的+偏移量。例如,11月8日星期日晚上8点+01:00。那标识了时间的唯一时刻。

标准方法通常是将即时存储为sql,TIMESTAMP WITH TIME ZONE并在Java方面使用a Timestamp或an OffsetDateTime