浪費時間
一個問題可能是java.sql.Date應該是...
「規範化」通過在特定的小時,分鍾,秒和毫秒設置爲零與實例關聯的時區。
......根據the documentation。這意味着,日期時間的時間部分將從java.util.Date或Joda-Time DateTime對象中清除。
沒有時區
隨着correct answer by Gilbert Le Blanc筆記,既java.util.Date和java.sql.Date沒有內部時區的概念。它們存儲自Unix epoch以來的毫秒數。
這些類拉一個討厭的把戲:他們的toString
方法將您的JVM的默認時區應用到字符串的呈現。很混亂。 Date
對象沒有時區,但在顯示爲字符串時會看到時區。
如果您的java.util.Date對象包含自紀元(1970年開始)以來的1344902399000L毫秒的數量,那意味着UTC/GMT中的2012-08-13T23:59:59.000Z
。但是如果你的JVM相信自己在法國的夏令時(DST)有效,你會看到UTC/GMT提前2小時:2012-08-14T01:59:59.000+02:00
在該類中描述的可怕的字符串格式。同一時刻在不同的時區有不同的日月含義(13對14),時鐘在牆上已經過了午夜。
喬達時間救援
的Joda-Time 2.4庫可以幫助這裏。將java.sql.Date或java.util.Date對象連同UTC time zone object一起傳遞給DateTime構造函數,以清楚地瞭解您掙扎的價值。
java.util.Date date = new java.util.Date(1390276603054L);
DateTime dateTimeUtc = new DateTime(date, DateTimeZone.UTC);
System.out.println("dateTimeUtc: " + dateTimeUtc);
運行時...
2014-01-21T03:56:43.054Z
要在另一方向喬達,時間java.util.Date轉換...
java.util.Date date = myDateTime.toDate();
要在另一方向喬達,時間轉換java.sql.Date ...
java.sql.Date date = new java.sql.Date(myDateTime.getMillis());
更新 - 時間
Joda-Time項目現在處於維護模式,團隊建議遷移到java.time類。
java.util.Date
的等價物是Instant
。 Instant
類表示UTC中時間軸上的一個時刻,分辨率爲nanoseconds(小數點後最多九(9)位數字)。
Instant instant = Instant.ofEpochMilli(1390276603054L);
應用時區,ZoneId
,產生ZonedDateTime
這是類似於一個java.util.Calendar
和喬達時間DateTime
。
ZoneId z = ZoneId.of("Europe/Kaliningrad");
ZonedDateTime zdt = instant.atZone(z);
現在提取一個日期只值,即ZonedDateTime
的日期部分,如一個LocalDate
。 LocalDate
類表示沒有時間和不帶時區的僅限日期的值。所以LocalDate
就是java.sql.Date
假裝是:僅限日期的價值。
LocalDate localDate = zdt.toLocalDate() ;
在JDBC 4.2和更高版本,您可以直接與兼容驅動程序通過PreparedStatement::setObject
和ResultSet::getObject
使用java.time類型。
myPreparedStatement.setObject(… , localDate);
...和...
LocalDate ld = myResultSet.getObject(… , LocalDate.class);
對於較舊的不兼容的驅動程序,簡單地轉換爲java.sql.Date
對象/從LocalDate
通過使用添加到老班的新方法:toLocalDate
和valueOf(LocalDate)
。
什麼是回來的路?是否:_new java.sql.Date(jodaDateTimeValue.withZone(DateTimeZone.UTC).getMillis())_? – 2014-02-20 09:41:58
@ thomas.mc.work不,從Joda-Time DateTime對象到java.util.Date比這更容易......只需調用'toDate'方法即可。像這樣:'java.util.Date date = myDateTime.toDate();'。對於java。** sql **。Date,您已經接近但不需要UTC,因爲Millis始終是UTC。所以:'java.sql.Date date = new java.sql.Date(myDateTime.getMillis());' – 2014-02-20 09:46:54
但是當我用這種方式從值「2014-02-01」的數據庫轉換java.sql.Date然後我得到「2014-01-31T23:00:00.000Z」(我的時區是CET)。當我使用時區CET時,它是正確的:「2014-02-01T00:00:00.000Z」。這是爲什麼? – 2014-02-20 13:23:52