我正在實施用於格式化插入到數據庫中的時間戳的功能。 對於此任務,現有解決方案使用SimpleDateFormat
。
由於SimpleDateFormat
不是線程安全的我將實現轉換爲java.time的使用。使用DateTimeFormatter設置「早期」日期的格式化時間戳
在這個過程中,我碰到了一些奇怪的行爲,其中格式呈現不同的結果。 下面的示例顯示在使用java.time
和1500-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跳過使用這些數據,但目前爲止沒有成功。
感謝您的回答。我想可以歸結爲在處理1582以前的數據時不要使用JSR 310. 我們正在實現的功能是數據庫數據的一般列表。我想在大多數情況下,用戶希望 在SQL和工具中輸入時看到相同的數據。即使數據庫中的實際時間戳在這種情況下也是錯誤的。 – user1239974