2017-10-06 123 views
3

我正在實施用於格式化插入到數據庫中的時間戳的功能。 對於此任務,現有解決方案使用SimpleDateFormat
由於SimpleDateFormat不是線程安全的我將實現轉換爲java.time的使用。使用DateTimeFormatter設置「早期」日期的格式化時間戳

在這個過程中,我碰到了一些奇怪的行爲,其中格式呈現不同的結果。 下面的示例顯示在使用java.time1500-01-01 00:00:00時如何使用SimpleDateFormat格式化爲"1500-01-10 00:12:12"
我不能承認爲什麼我們在使用java.time時需要9天休息。 12:12也來自哪裏。
使用'1500-01-01 00:00:00'將數據插入數據庫。
使用數據庫格式功能DATE_FORMAT呈現 預期輸出。

public static void main(String[] args) { 
    // The following ts value is obtained by debugging the Timestamp 
    // instance when reading data from MYSQL. 
    long ts = -14830995600000l; 
    String TSPATTERN = "yyyy-MM-dd HH:mm:ss"; 
    Timestamp timestamp = new Timestamp(ts); 
    System.out.println("       ZoneId: " + ZoneId.systemDefault()); 
    System.out.println("timestamp.toString() " + timestamp); 

    // java.time 
    DateTimeFormatter f = DateTimeFormatter.ofPattern(TSPATTERN).withZone(ZoneId.systemDefault()); 
    String withJavaTime = f.format(timestamp.toInstant()); 

    // Using SimpleDate format 
    SimpleDateFormat fdf = (SimpleDateFormat) SimpleDateFormat.getDateInstance(); 
    fdf.applyPattern(TSPATTERN); 
    String withSDF = fdf.format(ts); 
    System.out.println("  With java.time: " + withJavaTime); 
    System.out.println("With SimpleDateFormat: " + withSDF); 

    // Running the above will print the following output 
    // Where does the 12:12 come from? and the 9 days? 
    // With java.time: 1500-01-10 00:12:12 
    // With SimpleDateFormat: 1500-01-01 00:00:00 
} 

我還可以看到一個發散的輸出從數據庫函數DATE_FORMAT比較時和JSR 310能這樣不採取考慮ZoneOffsetTransition在JSR 310做數據庫解釋 ?

例如,格式化對應於「1899-12-31 01:00:00」的時間戳,使用JSR 310給出「1899-12-31 01:00:14」。 列出ZoneOffsetTransition爲我的(ZoneId Europe /斯德哥爾摩)給出以下(不完整的清單),這可能解釋爲 14分鐘。 Transition [Overlap at 1879-01-01T00:00 + 01:12:12 to +01:00:14] Transition [Overlap at 1900-01-01T00:00 + 01:00:14 to +01:00]

我試圖找到一種方法來格式化時間戳,告訴JSR 310跳過使用這些數據,但目前爲止沒有成功。

+0

感謝您的回答。我想可以歸結爲在處理1582以前的數據時不要使用JSR 310. 我們正在實現的功能是數據庫數據的一般列表。我想在大多數情況下,用戶希望 在SQL和工具中輸入時看到相同的數據。即使數據庫中的實際時間戳在這種情況下也是錯誤的。 – user1239974

回答

0

代替SimpleDateFormat,您可以使用線程安全的FastDateFormat。

+2

這個問題不是關於'SimpleDateFormat'的替代方法 - 它還提到代碼正在遷移到'java.time' API(它比'FastDateFormat'更新並且也是線程安全的),所以這個答案真的沒有解決問題中提到的問題。 – 2017-10-06 14:20:40