2015-06-04 119 views
7

我有一个java.time.OffsetDateTime,我想转换为java.sql.Timestamp。由于Timestamp不存储任何偏移量信息,因此我会将所有日期/时间存储为数据库中的UTC。转换OffsetDateTime为UTC时间戳

如何转换OffsetDateTimeTimestamp这是在UTC?

编辑:

我相信这是答案,但它似乎是要转换为UTC颇为曲折的方式:

OffsetDateTime dateTime = OffsetDateTime.now(); 
Timestamp timestamp = Timestamp.valueOf(dateTime.atZoneSameInstant(ZoneId.of("Z")).toLocalDateTime()); 

回答

7

这将是一种转换方式并确保使用UTC。我认为这比使用纪元秒提出的解决方案要简洁一些。

Timestamp test = Timestamp.valueOf(entityValue.atZoneSameInstant(ZoneOffset.UTC).toLocalDateTime()); 
+0

这是错误的。如果'dateTime'包含'2015-10-23T12:44:43Z',你在时区UTC + 2,那么'timestamp'将举行'2015年10月23日14:44:43.0'并从所提供的结果不同答案中的解决方案('2015-10-23 12:44:43.0')。 – rve

+0

是的,Timestamp.from(即时)确实会将其转换为您当地的时区。另一种方式来做到这一点,确保它保持在UTC是“时间戳测试= Timestamp.valueOf(entityValue.atZoneSameInstant(ZoneOffset.UTC).toLocalDateTime());”我编辑了上面的答案反映了这一点。 – Notso

+1

澄清上述评论以备将来参考:以前我的回答指出Timestamp.from(entityValue.toInstant)会这样做。然而,虽然瞬时基本上是从时代开始的时间轴上的瞬间,但时间戳(从瞬时)返回到当地时区,如@rve所述。因此,一种实现这一点并确保它仍然在UTC的方式是'Timestamp test = Timestamp.valueOf(entityValue.atZoneSameInstant(ZoneOffset.UTC).toLocalDateTime());' – Notso

2

使用.toEpochSecond()拿到距基准日期秒#(以UTC表示),乘以1000并将其传递给构造函数Timestamp(因为它预期的毫秒数)。

new Timestamp(1000 * offsetDateTime.toEpochSecond()); 
+0

这将失去有关纳秒虽然 - 对不对? – Cheetah

+0

是的,也许你自己的答案更好。 – Glorfindel

3

另一解决方案是:

Timestamp.valueOf(LocalDateTime.ofInstant(dateTime.toInstant(), ZoneOffset.UTC)); 

它转换dateTime为UTC,剥去时区信息,然后将结果提供给转换Timestamp。它仍然令人费解,但恕我直言,它有点干净。

只是使用toInstance()toEpochSeconds()将调整以偏移提供的结果。

以下显示这个测试结果和其他答案:

OffsetDateTime dateTime = 
    OffsetDateTime.of(2015, 10, 23, 12, 44, 43, 0, ZoneOffset.UTC); 
    // OffsetDateTime.of(2015, 10, 23, 12, 44, 43, 0, ZoneOffset.ofHours(-5)); 

err.println("dateTime   = " 
    + dateTime 
); 

err.println("as LocalDateTime = " 
    + dateTime.toLocalDateTime() 
); 

err.println("as timestamp (mine) = " 
    + Timestamp.valueOf(LocalDateTime.ofInstant(dateTime.toInstant(), ZoneOffset.UTC)) 
); 

err.println("@Cheetah (correct) = " 
    + Timestamp.valueOf(dateTime.atZoneSameInstant(ZoneId.of("Z")) 
     .toLocalDateTime()) 
); 

err.println("@Notso (wrong)  = " 
    + Timestamp.from(dateTime.toInstant()) 
); 

err.println("@Glorfindel (wrong) = " 
    + new Timestamp(1000 * dateTime.toEpochSecond()) 
); 

它的结果如下(我的时区是CET):

(with ZoneOffset.UTC) 
dateTime   = 2015-10-23T12:44:43Z 
as LocalDateTime = 2015-10-23T12:44:43 
as timestamp (mine) = 2015-10-23 12:44:43.0 
@Cheetah (correct) = 2015-10-23 12:44:43.0 
@Notso (wrong)  = 2015-10-23 14:44:43.0 
@Glorfindel (wrong) = 2015-10-23 14:44:43.0 

(with ZoneOffset.ofHours(-5)) 
dateTime   = 2015-10-23T12:44:43-05:00 
as LocalDateTime = 2015-10-23T12:44:43 
as timestamp (mine) = 2015-10-23 17:44:43.0 
@Cheetah (correct) = 2015-10-23 17:44:43.0 
@Notso (wrong)  = 2015-10-23 19:44:43.0 
@Glorfindel (wrong) = 2015-10-23 19:44:43.0 

(从Notso版本上面他2016年2月17日)的编辑之前