2012-11-06 60 views
26

我試圖從數據庫中獲取時間戳記值,將它們轉換爲日曆並將它們轉換回時間戳記,但它們失去了精度。將java.sql.Timestamp轉換爲java.util.Calendar時不會損失精度

下面的代碼來重現問題

import java.sql.Timestamp; 
import java.util.Calendar; 

public class Test { 
    public static void main(String[] args) 
    { 
     Timestamp timestamp = new Timestamp(112, 10, 5, 15, 39, 11, 801000000); 
     System.out.println("BEFORE "+timestamp.toString()); 
     Calendar calendar = Calendar.getInstance(); 
     calendar.setTimeInMillis(timestamp.getTime()); 
     timestamp = new Timestamp(calendar.getTimeInMillis()); 
     System.out.println("AFTER "+timestamp.toString()); 
    } 
} 

這裏是轉換

BEFORE 2012-10-18 14:30:13.362001 
AFTER 2012-10-18 14:30:13.362 

它失去了它的精確度的樣品結果。 我該如何保持小數值?

+0

我試過這個在我的IDE,但我沒有得到這樣的結果,每次打印相同 - 'Calendar calendar = Calendar.getInstance(); \t \t Timestamp timestamp = new Timestamp(new Date()。getTime()); \t \t System.out.println(「1 - >」+ timestamp); // \t \t Thread.currentThread()。sleep(1000); \t \t calendar.setTimeInMillis(timestamp.getTime()); \t \t timestamp = new Timestamp(calendar.getTimeInMillis()); \t \t System.out.println(「2 - >」+ timestamp);' –

+0

你能提供更多的上下文嗎?你在哪裏得到這些時間戳,你如何輸出它們? – axtavt

+0

我已經更新了這個例子,我很抱歉之前的錯誤結果是我的錯。 – William

回答

25

要設置在毫秒的時間,但你的輸入精度爲微秒,所以當然你將失去任何精密細於毫秒。

日曆不支持比毫秒更細的粒度。沒有解決方法。

+0

那麼,解決方法是什麼? – William

+2

@William沒有一個。見編輯的答案。 – Bohemian

+0

而且沒有其他的課程? – William

8

java.time

在Java 8後來我們現在有一個解決方案:新java.time框架是建立在由JSR 310定義,通過Joda-Time的啓發,由ThreeTen-Extra項目擴展。

這個新框架有nanosecond分辨率。這足以處理舊的java.util.Date值Joda-Time值,它們都是milliseconds。並且它足以處理microseconds,這些數據庫由Postgres等數據庫使用。一些數據庫如H2使用納秒。所以java.time可以處理這一切,或者至少所有的主流情況。唯一的例外將是利基科學或工程情況。

Image

使用Java 8,老班得到了新的方法從java.time轉換成/。在java.sql.Timestamp使用新的toInstantfromInstant方法。 Instant類包含從1970年UTC時代(基本上參見class doc獲取詳細信息)的時代開始的納秒數。

Instant您可以得到一個ZonedDateTime對象。

java.sql.Timestamp ts = myResultSet.getTimestamp(1); 
Instant instant = ts.toInstant(); 
ZoneId zoneId = ZoneId.of("America/Montreal"); 
ZonedDateTime zdt = instant.atZone(zoneId); 
相關問題