2015-06-04 117 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日)的編輯之前